2 part forth
1デフォルトの名無しさん
NGNG 第四世代
421デフォルトの名無しさん
2008/10/03(金) 06:08:32 : pushTOStoReturnStack postpone >r ; immediate
: popFromReturnStackToTOS postpone r> ; immediate
: popFromReturnStackToTOS postpone r> ; immediate
422デフォルトの名無しさん
2008/10/03(金) 12:26:50 自分も420に賛成する、forthは裸の2スタックマシンのアセンブラと思えばいいんだけど、それがつらいとちょっときついと思う
ただ、それがインタラクティブ環境を作るあたりと小さな核で構築できるのが非常に面白いのでがんばって覚えてみてよ。
逆に言うと簡単にぶっ壊れるとも言う
ただ、それがインタラクティブ環境を作るあたりと小さな核で構築できるのが非常に面白いのでがんばって覚えてみてよ。
逆に言うと簡単にぶっ壊れるとも言う
423デフォルトの名無しさん
2008/10/03(金) 16:59:48 Cとかの他の言語の常識持ち込もうとしてるヤツいないか?
「Forthではこう書く」ってのに納得いかないなら
悪いことは言わんから、使うのやめとけ
「Forthではこう書く」ってのに納得いかないなら
悪いことは言わんから、使うのやめとけ
424デフォルトの名無しさん
2008/10/03(金) 17:54:20 スタックっつうのはあくまで機械にやさしいものであってユーザーフレンドリーなものじゃないしな
425デフォルトの名無しさん
2008/10/03(金) 18:38:23 頻繁にスタックを意識しないといけないのは悪いForthコード
426デフォルトの名無しさん
2008/10/03(金) 20:05:40 正直アセンブラの方が楽だよ
427デフォルトの名無しさん
2008/10/03(金) 20:24:33 慣れると気持ちいいよJoy。forthは知らんけど
428デフォルトの名無しさん
2008/10/03(金) 20:29:08 >426
Forthは仮想スタックマシンのアセンブラだから、
(仮想)マシンの理解度によるだろな。
Forthは仮想スタックマシンのアセンブラだから、
(仮想)マシンの理解度によるだろな。
429デフォルトの名無しさん
2008/10/03(金) 22:29:45 いや、もっと視認しやすい記号セットを使ってくれって話だろ。
ハイライトできるエディタで単語登録するか、トランスレータでもかますのがいいと思う。
ハイライトできるエディタで単語登録するか、トランスレータでもかますのがいいと思う。
430デフォルトの名無しさん
2008/10/03(金) 23:01:49 ところでリターンスタックって別に必要なの?
普通のCPUは1本だよね。
スタックに対して相対アドレッシングがないからってことかな?
普通のCPUは1本だよね。
スタックに対して相対アドレッシングがないからってことかな?
431デフォルトの名無しさん
2008/10/03(金) 23:57:29 >419
>rとr>は確かに見た目がわかりにくい。
よほどのことが無い限り使わない。
localがあれば要らない。
>430
呼出しのときにデータスタックで直接パラメターを渡すためでしょう。
>rとr>は確かに見た目がわかりにくい。
よほどのことが無い限り使わない。
localがあれば要らない。
>430
呼出しのときにデータスタックで直接パラメターを渡すためでしょう。
432デフォルトの名無しさん
2008/10/04(土) 00:00:27 >>430
普通のアーキテクチャだと関数呼び出しのスタックにパラメータも突っ込んじゃうけど
forthはデータのpushと関数呼び出しの戻りアドレスが入るスタックが別なんよ。
っていうか別だから面白いことができるので、一緒だったらループとかで涙が出そうだと思う。
普通のアーキテクチャだと関数呼び出しのスタックにパラメータも突っ込んじゃうけど
forthはデータのpushと関数呼び出しの戻りアドレスが入るスタックが別なんよ。
っていうか別だから面白いことができるので、一緒だったらループとかで涙が出そうだと思う。
433デフォルトの名無しさん
2008/10/04(土) 00:10:21 SP, BPレジスタに相当するものがあれば良いのでは
434デフォルトの名無しさん
2008/10/04(土) 17:45:11 リターンスタックとデータスタックが一緒だと、
リターンアドレスを壊さないようにデータをいじるのがメンドイ。
リターンアドレスが詰まれている位置を避けるようにして
スタックをアクセスしなきゃいけないから。
それはSPとBPがあってもメンドイことに変わりはない。
リターンアドレスを壊さないようにデータをいじるのがメンドイ。
リターンアドレスが詰まれている位置を避けるようにして
スタックをアクセスしなきゃいけないから。
それはSPとBPがあってもメンドイことに変わりはない。
435デフォルトの名無しさん
2008/10/04(土) 19:46:33436デフォルトの名無しさん
2008/10/04(土) 21:37:24 factorだともうひとつスタックあるよ
437デフォルトの名無しさん
2008/10/04(土) 23:25:44 データスタックとリターンスタックがないと
チューリングマシンと等価じゃないらしいぞ
チューリングマシンと等価じゃないらしいぞ
438デフォルトの名無しさん
2008/10/05(日) 00:17:09439デフォルトの名無しさん
2008/10/05(日) 01:12:05 今理解した。
リターンスタックってそのままBP相当じゃん。
ほんとはBPポインタ一個あれば十分だよね?
素直にBPを持たずにわざわざリターンスタックなんて用意してるのは、
スタックマシンと言えなくなるからかね。
なんだかなあ。
リターンスタックってそのままBP相当じゃん。
ほんとはBPポインタ一個あれば十分だよね?
素直にBPを持たずにわざわざリターンスタックなんて用意してるのは、
スタックマシンと言えなくなるからかね。
なんだかなあ。
440デフォルトの名無しさん
2008/10/05(日) 03:10:12 BPあってもメモリがないとな
441デフォルトの名無しさん
2008/10/05(日) 03:49:49 今理解した。
BPってそのままリターンスタック相当じゃん。
ほんとはリターンスタックあれば十分だよね?
素直にリターンスタックを持たずに、わざわざBPなんて用意してるのは、
レジスタマシンと言えなくなるからかね。
なんだかなあ。
BPってそのままリターンスタック相当じゃん。
ほんとはリターンスタックあれば十分だよね?
素直にリターンスタックを持たずに、わざわざBPなんて用意してるのは、
レジスタマシンと言えなくなるからかね。
なんだかなあ。
442デフォルトの名無しさん
2008/10/05(日) 07:20:41 >>437
メモリアクセスできない純粋なスタックマシンなら、スタックが二本ないと
チューリング等価ではないかも知れないが、FORTHはメモリアクセス @ ! が
あるから、たとえスタック一本であってもチューリング等価じゃね?
考えてみればわかるが、メモリアクセスがあるとスタックの本数を自由に増やせる。
FORTHとスタックマシンとConcatenative言語は、それぞれ別の概念で、
単純に等号で結べないから、何について話しているのか意識しないと混乱すると思われ。
メモリアクセスできない純粋なスタックマシンなら、スタックが二本ないと
チューリング等価ではないかも知れないが、FORTHはメモリアクセス @ ! が
あるから、たとえスタック一本であってもチューリング等価じゃね?
考えてみればわかるが、メモリアクセスがあるとスタックの本数を自由に増やせる。
FORTHとスタックマシンとConcatenative言語は、それぞれ別の概念で、
単純に等号で結べないから、何について話しているのか意識しないと混乱すると思われ。
443デフォルトの名無しさん
2008/10/05(日) 09:51:29 ForthのVMとしては、
論理的には最低限二つの区別されたスタックがある。
標準的な実装での利点(v.s.スタックフレーム方式)は、
サブルーチン間でのデータのコピーが減らせること。
スタックフレーム一本でやるのはCとかでも標準的な実装だけど、
VMという同じ抽象度で比べれば、Cにはスタックは無い。
VMが実装できれば機械自体の仕組みはどうでも良い。
論理的には最低限二つの区別されたスタックがある。
標準的な実装での利点(v.s.スタックフレーム方式)は、
サブルーチン間でのデータのコピーが減らせること。
スタックフレーム一本でやるのはCとかでも標準的な実装だけど、
VMという同じ抽象度で比べれば、Cにはスタックは無い。
VMが実装できれば機械自体の仕組みはどうでも良い。
444デフォルトの名無しさん
2008/10/05(日) 13:26:57 込み入った話は分からんけど、
とりあえずBF書けたらチューリング完全じゃなかったっけ?
とりあえずBF書けたらチューリング完全じゃなかったっけ?
445デフォルトの名無しさん
2008/10/05(日) 14:12:31 なんか話が噛み合ってない気がする。
446デフォルトの名無しさん
2008/10/05(日) 15:11:57 なんでそこまでチューリングマシンにこだわるのかわからん。
Forthがチューリングマシンであろうとなかろうと
Forthで実用的なプログラムは書ける。
あともう一人、やたらリターンスタックを排除したがる奴も
何をしたいのかさっぱりわからん。
Forthがチューリングマシンであろうとなかろうと
Forthで実用的なプログラムは書ける。
あともう一人、やたらリターンスタックを排除したがる奴も
何をしたいのかさっぱりわからん。
447デフォルトの名無しさん
2008/10/05(日) 17:47:31 まず当たり前の大前提の確認からだけど、Forthはチューリング完全だから。
仮にForthの仕様からリターンスタックだけを排除したとしても(それはForthとは呼べないだろうが)
チューリング完全だ。理由は>>442
リターンスタックがBPで代用できるとか正直意味わからん。
スタック演算自体理解してない希ガス。
仮にForthの仕様からリターンスタックだけを排除したとしても(それはForthとは呼べないだろうが)
チューリング完全だ。理由は>>442
リターンスタックがBPで代用できるとか正直意味わからん。
スタック演算自体理解してない希ガス。
448デフォルトの名無しさん
2008/10/05(日) 18:27:08 リターンスタックという名前がいかんのだろ。
449デフォルトの名無しさん
2008/10/05(日) 18:35:04 >>437
スタックオートマトンとスタックマシンをごっちゃにしてる気がする。
スタックオートマトンとスタックマシンをごっちゃにしてる気がする。
450デフォルトの名無しさん
2008/10/05(日) 18:39:13 >>448
むしろリターンスタック以外の名前があるなら知りたいものだが。
むしろリターンスタック以外の名前があるなら知りたいものだが。
451デフォルトの名無しさん
2008/10/05(日) 19:02:41 >442
大雑把にはこんな感じかね。
・データスタック: 引数&戻り値
・リターンスタック: 実行する命令列(辞書で展開された単語含む)
リターンスタックというよりもオーダースタックといった方がちょうど良い気がするけどね
大雑把にはこんな感じかね。
・データスタック: 引数&戻り値
・リターンスタック: 実行する命令列(辞書で展開された単語含む)
リターンスタックというよりもオーダースタックといった方がちょうど良い気がするけどね
452デフォルトの名無しさん
2008/10/05(日) 19:25:44 リターンアドレスを積んでいるからリターンスタック
それでいいと思うが、難しく考えすぎじゃね?>>451
それでいいと思うが、難しく考えすぎじゃね?>>451
453デフォルトの名無しさん
2008/10/05(日) 19:28:44 Aスタック←→Bスタック
だったら勘違いが起きなかったと思う。
だったら勘違いが起きなかったと思う。
454デフォルトの名無しさん
2008/10/05(日) 19:34:19 >>453
むしろ勘違いを引き起こしそうなんだが。
リターンスタックが難しいんじゃなくて、
リターンアドレスをスタックに積むという
当たり前の関数呼び出し規約を説明しなければ、
理解されない時代になったということか…
むしろ勘違いを引き起こしそうなんだが。
リターンスタックが難しいんじゃなくて、
リターンアドレスをスタックに積むという
当たり前の関数呼び出し規約を説明しなければ、
理解されない時代になったということか…
455デフォルトの名無しさん
2008/10/05(日) 21:59:43 なんでリターンスタックの名前で混乱とか勘違いがあるの?
ひょっとして、リターンと聞いて戻り値を連想しちゃう人がいる、とか?
だとしたらかなりキビシい状況だな。
ひょっとして、リターンと聞いて戻り値を連想しちゃう人がいる、とか?
だとしたらかなりキビシい状況だな。
456デフォルトの名無しさん
2008/10/06(月) 01:09:11 カールスタックの方が一般的じゃね?
457デフォルトの名無しさん
2008/10/06(月) 01:09:52 あ、カールじゃなくてコールスタック
458デフォルトの名無しさん
2008/10/06(月) 01:24:45 カールはスナックだな
459デフォルトの名無しさん
2008/10/06(月) 07:35:22 カールと言えば薄べったいのが出てることを最近知った。
従来品に比べて口の裏に張り付きにくいのはメリットだが、
少し物足りない気がした。
従来品に比べて口の裏に張り付きにくいのはメリットだが、
少し物足りない気がした。
460デフォルトの名無しさん
2008/10/06(月) 11:21:56 Forth では昔からリターンスタックと呼んできたので、その伝統に則ればいいと
思うんだけどな。Wikipedia だと項目はコールスタックで立てられているが。
思うんだけどな。Wikipedia だと項目はコールスタックで立てられているが。
461デフォルトの名無しさん
2008/10/06(月) 12:10:36 コールスタック->カールスナック->コーンスターチ->張り付かないならカールじゃない
勉強し過ぎでしょう。
勉強し過ぎでしょう。
462461
2008/10/06(月) 12:30:27 補:そもそもForthが一般的じゃない
463デフォルトの名無しさん
2008/10/06(月) 21:49:04 ・リターンスタックが普通のCPUで言うとことの「スタック」。
ワード(Cで言うところの関数、実際にはサブルーチン)
を呼ぶと呼び出し戻るためのアドレスを積む。
# 普通のCPUでCALL命令(68系だとBSR、JSR)を実行すると
# リターンアドレスがスタックに積まれるのは理解しているよね?
・データスタックってのは、言ってみれば「無限に増えるアキュムレータ」って感じ。
・「辞書」が命令コードストレージ、C言語でいえばTEXTセグメント
Forthの本質は上記3点をおさえて置けば理解できるんだが。
BPがリターンスタックと等価なんて言ってる人とか、
>・リターンスタック: 実行する命令列(辞書で展開された単語含む)
>リターンスタックというよりもオーダースタックといった方がちょうど良い気がするけどね
なんて言っている人、本当に理解できてるの?
ワード(Cで言うところの関数、実際にはサブルーチン)
を呼ぶと呼び出し戻るためのアドレスを積む。
# 普通のCPUでCALL命令(68系だとBSR、JSR)を実行すると
# リターンアドレスがスタックに積まれるのは理解しているよね?
・データスタックってのは、言ってみれば「無限に増えるアキュムレータ」って感じ。
・「辞書」が命令コードストレージ、C言語でいえばTEXTセグメント
Forthの本質は上記3点をおさえて置けば理解できるんだが。
BPがリターンスタックと等価なんて言ってる人とか、
>・リターンスタック: 実行する命令列(辞書で展開された単語含む)
>リターンスタックというよりもオーダースタックといった方がちょうど良い気がするけどね
なんて言っている人、本当に理解できてるの?
464デフォルトの名無しさん
2008/10/07(火) 00:25:52 >463
いや、別にWORDがサブルーチンである必要はないんじゃない?WORD毎の環境要らないんだし。
Cとの相性を考えるとサブルーチンにした方が良いと思うけど。
あと、CPUのアーキテクチャには疎いんだけど、最近のCPUでスタック持ってるのってあったっけ?
いや、別にWORDがサブルーチンである必要はないんじゃない?WORD毎の環境要らないんだし。
Cとの相性を考えるとサブルーチンにした方が良いと思うけど。
あと、CPUのアーキテクチャには疎いんだけど、最近のCPUでスタック持ってるのってあったっけ?
465デフォルトの名無しさん
2008/10/07(火) 06:15:51466デフォルトの名無しさん
2008/10/07(火) 06:37:45 >>464
前半は実装と仕様が混乱してそう。
後半は、たぶん、CPUの「レジスタアーキテクチャ」「スタックアーキテクチャ」と
データ構造としてのスタックを混同している。
Wikipediaやblog読んで理解した気にならないで実際に自分で手を動かしてみなよ。
ちょっと恥ずかし過ぎるぞ、あんた。
前半は実装と仕様が混乱してそう。
後半は、たぶん、CPUの「レジスタアーキテクチャ」「スタックアーキテクチャ」と
データ構造としてのスタックを混同している。
Wikipediaやblog読んで理解した気にならないで実際に自分で手を動かしてみなよ。
ちょっと恥ずかし過ぎるぞ、あんた。
467デフォルトの名無しさん
2008/10/07(火) 12:34:16468デフォルトの名無しさん
2008/10/07(火) 13:28:27 post,preのincやdec付きレジスタ間接参照命令があればデータスタックと等価だよね?
リターンスタックってのはサブルーチンコール時に戻りアドレスをpushする為のレジスタの事でしょう?
なら今時のCPUで無い物の方が珍しいと思うんだけど
リターンスタックってのはサブルーチンコール時に戻りアドレスをpushする為のレジスタの事でしょう?
なら今時のCPUで無い物の方が珍しいと思うんだけど
469デフォルトの名無しさん
2008/10/07(火) 20:49:02 x86って俺の生まれる前からあるな。
定年過ぎた方には最近なんでしょうけど。
定年過ぎた方には最近なんでしょうけど。
470デフォルトの名無しさん
2008/10/07(火) 21:09:44 定年過ぎて無く立ってプロセッサ自体30年の歴史しかないじゃないか
471デフォルトの名無しさん
2008/10/07(火) 21:36:31 最近のCPUは古いアーキテクチャのものがほとんどだよね。
細かいところは違うんだろが。
>>468
>戻りアドレスをpushする為のレジスタ
レジストリって意味?
RISCだと、戻りアドレスを保存するレジスタがあること多いよね。
まあ、リターンスタックは、
リターンアドレスを積むため専用(原則)のスタック
ってことがわかれば、いいじゃない。
データスタックと別にある利点もわかってるわけでしょ。
本当は「リターンスタックがあること」じゃなくて、
データスタックが複数のワードを横断して固定されていること、
の方が特徴だよね。
普通の言語の実装だと、
データスタックがサブルーチンごとに別々にリターンスタックの中にあって、
受け渡すデータはコピーする、
という感じなわけだ。比喩的に言えば。
アセンブリレベルでもリターンアドレスのpush/popが自動になってるなら、
気付かない人がいてもしょうがない。
細かいところは違うんだろが。
>>468
>戻りアドレスをpushする為のレジスタ
レジストリって意味?
RISCだと、戻りアドレスを保存するレジスタがあること多いよね。
まあ、リターンスタックは、
リターンアドレスを積むため専用(原則)のスタック
ってことがわかれば、いいじゃない。
データスタックと別にある利点もわかってるわけでしょ。
本当は「リターンスタックがあること」じゃなくて、
データスタックが複数のワードを横断して固定されていること、
の方が特徴だよね。
普通の言語の実装だと、
データスタックがサブルーチンごとに別々にリターンスタックの中にあって、
受け渡すデータはコピーする、
という感じなわけだ。比喩的に言えば。
アセンブリレベルでもリターンアドレスのpush/popが自動になってるなら、
気付かない人がいてもしょうがない。
472464
2008/10/07(火) 23:32:13 >465
いや、スタックポインタ(レジスタ)じゃなくてスタック。>467 の通りですな。>463で『アドレスを積む』とか
書いているからHWスタックのことかと思った。
スタックを内部に持つCPUの話があった記憶があったので勘違いしたわ。すまんね。
forthあんまり詳しくないんで済まんのだけど、『リターンスタックには、ワードを呼ぶと呼び出し戻るため
のアドレスを積む』んだっけ?
正規化の観点からは『まだ実行していないWORD』もリターンスタックに積めた方が便利だと思うけど。
WORDコンパイルの実装で手が抜けなくなるし……
いや、スタックポインタ(レジスタ)じゃなくてスタック。>467 の通りですな。>463で『アドレスを積む』とか
書いているからHWスタックのことかと思った。
スタックを内部に持つCPUの話があった記憶があったので勘違いしたわ。すまんね。
forthあんまり詳しくないんで済まんのだけど、『リターンスタックには、ワードを呼ぶと呼び出し戻るため
のアドレスを積む』んだっけ?
正規化の観点からは『まだ実行していないWORD』もリターンスタックに積めた方が便利だと思うけど。
WORDコンパイルの実装で手が抜けなくなるし……
473デフォルトの名無しさん
2008/10/07(火) 23:56:37474デフォルトの名無しさん
2008/10/08(水) 04:22:01 >>469
いまでも現役バリバリで使われていて
マイクロソフトの最新OS「VISTA」がポーティングされる
x86アーキテクチャが「最近のCPU」では無いとでも?
あるいはCore2DUOとかがX86アーキテクチャじゃないとでも思ってる?
いまでも現役バリバリで使われていて
マイクロソフトの最新OS「VISTA」がポーティングされる
x86アーキテクチャが「最近のCPU」では無いとでも?
あるいはCore2DUOとかがX86アーキテクチャじゃないとでも思ってる?
475デフォルトの名無しさん
2008/10/08(水) 06:31:12 >>472
Forthと関係なく、関数の呼び出し元に戻るためにアドレスをスタックに積む、
という動作は、アセンブリレベルでは普通の関数呼び出し規約。
Forthは言語レベルでリターンスタックを操作できる言語だけど、
普通は意識しなくてもいいから、リターンアドレスが何のために存在しているのか
理解できない人がいても不思議じゃないけど、せめてもう少し自分で勉強して欲しい。
Forthと関係なく、関数の呼び出し元に戻るためにアドレスをスタックに積む、
という動作は、アセンブリレベルでは普通の関数呼び出し規約。
Forthは言語レベルでリターンスタックを操作できる言語だけど、
普通は意識しなくてもいいから、リターンアドレスが何のために存在しているのか
理解できない人がいても不思議じゃないけど、せめてもう少し自分で勉強して欲しい。
476デフォルトの名無しさん
2008/10/08(水) 06:35:19 >forthあんまり詳しくないんで済まんのだけど、
とか、逃げをうたず自分で触ってみろよ。
とか、逃げをうたず自分で触ってみろよ。
477デフォルトの名無しさん
2008/10/08(水) 14:37:36 441だけど盛り上がってるね。
自分なりのまとめ。
リターンスタックはBPとcall/retの役割がある。
call/retを他の命令で書くと
・関数の呼び出し
push $LNEXT
jmp func
$LNEXT:
・関数のret
pop ecx ; $LNEXTのアドレスがecxに入る
jmp [ecx]
・関数のはじめ
push ebp
mov ebp, esp
・関数のおわり
mov esp, ebp
pop ebp
こうなる。
つまりBPはリターンスタックのトップと同じ。
BPを基点にすればデータスタックだけでも同じ事ができる。
「ボクが考えたforth」ではリターンスタックは必要ない。
自分なりのまとめ。
リターンスタックはBPとcall/retの役割がある。
call/retを他の命令で書くと
・関数の呼び出し
push $LNEXT
jmp func
$LNEXT:
・関数のret
pop ecx ; $LNEXTのアドレスがecxに入る
jmp [ecx]
・関数のはじめ
push ebp
mov ebp, esp
・関数のおわり
mov esp, ebp
pop ebp
こうなる。
つまりBPはリターンスタックのトップと同じ。
BPを基点にすればデータスタックだけでも同じ事ができる。
「ボクが考えたforth」ではリターンスタックは必要ない。
478デフォルトの名無しさん
2008/10/08(水) 18:17:31479デフォルトの名無しさん
2008/10/08(水) 18:47:05 で、その「ボクが考えたforth」では、
パラメタはどうやって渡すんだ?
パラメタはどうやって渡すんだ?
480デフォルトの名無しさん
2008/10/08(水) 19:05:03 どう考えても普通にCALL/RETした方が速そうだけど
わざわざ面倒くさくしてどうするの?
あと、ENTER/LEAVEとか使わないの
わざわざ面倒くさくしてどうするの?
あと、ENTER/LEAVEとか使わないの
481デフォルトの名無しさん
2008/10/08(水) 21:00:40 >>477
もはやどこから突っ込んで良いものやら…
二つほど疑問が。
一つ目。
>>479も言ってるけれど、その実装だとパラメタの受け渡しが面倒そうなのだが。
たとえば、その実装方法で、
: foo drop drop 3 4 5 ;
1 2 foo
としたときにスタックがどのように変化していくのか書いてみてくれ。
解決方法を考えられなくもないが、たぶん独立したリターンスタックが
あるほうがシンプルだと思われ。
二つ目。
リターンスタックを操作する命令はどうやって実装するの?
これも独立したリターンスタックがあるほうがシンプルだと思われ。
forthじゃない何かをつくろうとしているのだろうか?
もはやどこから突っ込んで良いものやら…
二つほど疑問が。
一つ目。
>>479も言ってるけれど、その実装だとパラメタの受け渡しが面倒そうなのだが。
たとえば、その実装方法で、
: foo drop drop 3 4 5 ;
1 2 foo
としたときにスタックがどのように変化していくのか書いてみてくれ。
解決方法を考えられなくもないが、たぶん独立したリターンスタックが
あるほうがシンプルだと思われ。
二つ目。
リターンスタックを操作する命令はどうやって実装するの?
これも独立したリターンスタックがあるほうがシンプルだと思われ。
forthじゃない何かをつくろうとしているのだろうか?
482デフォルトの名無しさん
2008/10/08(水) 21:16:43 二つ目用の問題も書いておくよ。
: bar 1 2 3 >r >r 1 + r> r> ;
: bar 1 2 3 >r >r 1 + r> r> ;
483デフォルトの名無しさん
2008/10/08(水) 23:38:28 混乱してるようだから、
まず、ネイティブの場合とスレッディングの場合を分けて考えた方がいい。
ネイティブForthで自然な実装では、
SP=リターンスタックポインタ(RSP)
BP=データスタックポインタ(DSP)
となってる。
UNIX/Cの普通のスタックを知ってれば、機能的な対応は明瞭なはず。
リターンスタックが伸びても、DSPは別フレームに移らないのがForthのポイント。
ちなみに、Forthでも局所変数が使えるヤツがあって、
その局所変数には、リタースタック中にフレームを作って割り当てるのが普通。
これも、標準のスタックがわかってれば意味は明瞭。
スレッディング(直接・間接)方式だと、
呼出しはCallじゃないから、
BPをRSPにしてもかまわんが、
パラメタとリターンアドレスの混合は、
Forthでは無謀。動的にチェックが必要な上に、完璧にはできそうにない。
まず、ネイティブの場合とスレッディングの場合を分けて考えた方がいい。
ネイティブForthで自然な実装では、
SP=リターンスタックポインタ(RSP)
BP=データスタックポインタ(DSP)
となってる。
UNIX/Cの普通のスタックを知ってれば、機能的な対応は明瞭なはず。
リターンスタックが伸びても、DSPは別フレームに移らないのがForthのポイント。
ちなみに、Forthでも局所変数が使えるヤツがあって、
その局所変数には、リタースタック中にフレームを作って割り当てるのが普通。
これも、標準のスタックがわかってれば意味は明瞭。
スレッディング(直接・間接)方式だと、
呼出しはCallじゃないから、
BPをRSPにしてもかまわんが、
パラメタとリターンアドレスの混合は、
Forthでは無謀。動的にチェックが必要な上に、完璧にはできそうにない。
484464
2008/10/09(木) 01:15:39 446です。
forthは興味半分で使ったレベルでしかないですね……
concatenative俺言語の設計の参考にしているぐらいです。
>473
リターンスタックを「次に実行する命令の列」という形に抽象化すると、「現在処理中のWORD」と
「ソースコードを解釈したWORD」「Dictionaryに保持されているWORD列」…つまり呼び出されて
いないWORDを対称(等価/交換可能)に扱うことができるようになるので、バーチャルマシンの
構造を簡単化することができるかと思います。
……forthで許されているのかしらんけど。
forthは興味半分で使ったレベルでしかないですね……
concatenative俺言語の設計の参考にしているぐらいです。
>473
リターンスタックを「次に実行する命令の列」という形に抽象化すると、「現在処理中のWORD」と
「ソースコードを解釈したWORD」「Dictionaryに保持されているWORD列」…つまり呼び出されて
いないWORDを対称(等価/交換可能)に扱うことができるようになるので、バーチャルマシンの
構造を簡単化することができるかと思います。
……forthで許されているのかしらんけど。
485デフォルトの名無しさん
2008/10/09(木) 06:24:10 リターンスタックに積んであるリターンアドレスは、
「これから実行される命令列」へのポインタそのものと見なせるから、
そのアイデアが新しいとは思えないけどな。
Forthぐらいバーチャルマシンの実装が簡単な言語もないし。
ただ、リターンスタックの意味がよくわからないままに、
他の言語のように抽象構文木を再帰的に処理するような
実装にしていると、リターンスタック操作の実装で悩むの
かもしれない。
「これから実行される命令列」へのポインタそのものと見なせるから、
そのアイデアが新しいとは思えないけどな。
Forthぐらいバーチャルマシンの実装が簡単な言語もないし。
ただ、リターンスタックの意味がよくわからないままに、
他の言語のように抽象構文木を再帰的に処理するような
実装にしていると、リターンスタック操作の実装で悩むの
かもしれない。
486464
2008/10/09(木) 08:54:40 >485
>463は呼び出したWORDを積むことを前提にしているし、>451 >472で言ってるのが >463 >473で
思い切り否定されてるので、forthじゃそういう考え方無いのかな、と思った。
もしforthでもそういう使い方しているんだったらおいらの不勉強だね。
>463は呼び出したWORDを積むことを前提にしているし、>451 >472で言ってるのが >463 >473で
思い切り否定されてるので、forthじゃそういう考え方無いのかな、と思った。
もしforthでもそういう使い方しているんだったらおいらの不勉強だね。
487デフォルトの名無しさん
2008/10/09(木) 10:46:32 >>486
485のいってる意味は、
スレッディング方式のforthでは、
辞書は実行されるワードのポインタのリストとみなせるわけで、
リターンアドレスというのは、辞書内への戻りアドレス、
つまり、これから実行されるワードのリストへのポインタといえる
ということと思われる。
ワードのポインタを直接リターンスタックに積み込むような、
インストラクションキャッシュみたいな仕様のリターンスタックの実装は、
ちょっと聞いたことが無い。
というかそれじゃリターンスタックじゃない。
485のいってる意味は、
スレッディング方式のforthでは、
辞書は実行されるワードのポインタのリストとみなせるわけで、
リターンアドレスというのは、辞書内への戻りアドレス、
つまり、これから実行されるワードのリストへのポインタといえる
ということと思われる。
ワードのポインタを直接リターンスタックに積み込むような、
インストラクションキャッシュみたいな仕様のリターンスタックの実装は、
ちょっと聞いたことが無い。
というかそれじゃリターンスタックじゃない。
488デフォルトの名無しさん
2008/10/09(木) 20:52:04 487の言わんとすることを俺なりに解釈してみる…
: foo dup + ;
: bar foo drop ;
bar の処理中に foo を実行するときに、
foo の次の drop のアドレスをリターンスタックに積む。
それで、foo の実行終了時にリターンアドレスから戻り先を取る。
これが、さっき積んだ drop のアドレスということ。
で、「drop のアドレス」っていうのを「ポインタ」と呼んでいる。
: foo dup + ;
: bar foo drop ;
bar の処理中に foo を実行するときに、
foo の次の drop のアドレスをリターンスタックに積む。
それで、foo の実行終了時にリターンアドレスから戻り先を取る。
これが、さっき積んだ drop のアドレスということ。
で、「drop のアドレス」っていうのを「ポインタ」と呼んでいる。
489デフォルトの名無しさん
2008/10/09(木) 21:08:57 fooが呼ばれたときのリターンアドレスは 「dropのアドレス」というより
「dropの直前のアドレス」だ。
微妙なニュアンスに聞こえるかもしれないが。
: bar foo ( ここ ) drop ;
( ここ ) と書いた部分に戻ってくる。
「dropの直前のアドレス」だ。
微妙なニュアンスに聞こえるかもしれないが。
: bar foo ( ここ ) drop ;
( ここ ) と書いた部分に戻ってくる。
490デフォルトの名無しさん
2008/10/09(木) 21:12:38 : foo dup + ;
: bar dup * ;
: baz foo ( ここ ) bar ( そこ ) ;
foo が呼ばれたときリターンスタックには( ここ )が積まれてる。
bar が呼ばれたときリターンスタックには( そこ )が積まれてる。
bar というワード自身がリターンスタックに積まれているのではない。
: bar dup * ;
: baz foo ( ここ ) bar ( そこ ) ;
foo が呼ばれたときリターンスタックには( ここ )が積まれてる。
bar が呼ばれたときリターンスタックには( そこ )が積まれてる。
bar というワード自身がリターンスタックに積まれているのではない。
491デフォルトの名無しさん
2008/10/09(木) 21:16:04 ついでに >>56 のリターンスタックを使ったパズルの説明でも書いておこう。
問題は、
: foo twice ." Hello" ;
で、
HelloHello
を出力する twice を定義しろというパズル。
問題は、
: foo twice ." Hello" ;
で、
HelloHello
を出力する twice を定義しろというパズル。
492デフォルトの名無しさん
2008/10/09(木) 21:22:30 解答は、
: twice r> dup >r >r ;
何が起きているか説明すると、twice が呼ばれたとき、リターンスタックには、
: foo twice ( ここ ) ." Hello" ;
上の( ここ )が積まれている。
twice は最初に r> を実行して、( ここ ) をリターンスタックからデータスタックに移している。
次の dup で ( ここ ) がデータスタックに二つ積まれた状態になる。
最後に、 二つの >r で ( ここ ) が二つリターンスタックに戻される。
: twice r> dup >r >r ;
何が起きているか説明すると、twice が呼ばれたとき、リターンスタックには、
: foo twice ( ここ ) ." Hello" ;
上の( ここ )が積まれている。
twice は最初に r> を実行して、( ここ ) をリターンスタックからデータスタックに移している。
次の dup で ( ここ ) がデータスタックに二つ積まれた状態になる。
最後に、 二つの >r で ( ここ ) が二つリターンスタックに戻される。
493デフォルトの名無しさん
2008/10/09(木) 21:27:12 さて、定義されたワードの終端に到達したので Forthは、
リターンスタックからリターンアドレスを一つ取り出してそこに戻ろうとする。
: foo twice ( ここ ) ." Hello" ;
↑これの ( ここ )に戻ってくるわけだね。
そして、Helloを出力する。
そしてまた定義されたワードの終端に到達するので、Forth は
リターンスタックからリターンアドレスを一つ取り出してそこに戻ろうとするわけだ。
つまり、もう一度 ( ここ ) に戻る。
もう一度、Helloが出力されたら、次にリターンスタックからpopされる
リターンアドレスは foo を呼び出したアドレスなので、ここでようやく、
foo の実行が終了することになる。
リターンスタックからリターンアドレスを一つ取り出してそこに戻ろうとする。
: foo twice ( ここ ) ." Hello" ;
↑これの ( ここ )に戻ってくるわけだね。
そして、Helloを出力する。
そしてまた定義されたワードの終端に到達するので、Forth は
リターンスタックからリターンアドレスを一つ取り出してそこに戻ろうとするわけだ。
つまり、もう一度 ( ここ ) に戻る。
もう一度、Helloが出力されたら、次にリターンスタックからpopされる
リターンアドレスは foo を呼び出したアドレスなので、ここでようやく、
foo の実行が終了することになる。
494デフォルトの名無しさん
2008/10/09(木) 21:29:45 リターンスタックに積まれているリターンアドレスは、
次に実行すべきワード単体ではなくて、
それ以降、実行すべきコード全体の先頭を指し示すアドレスだ、
と、理解できたかしらん?
次に実行すべきワード単体ではなくて、
それ以降、実行すべきコード全体の先頭を指し示すアドレスだ、
と、理解できたかしらん?
495488
2008/10/10(金) 00:34:56 (ここ) は分かってるつもりなんですが、
メモリアドレス的に的確に伝えるには難しいような気が。。。
: baz foo ( ここ ) bar ( そこ ) ;
16bitアドレス環境として、スレデッドコードで考えると、
(ここ)は foo のアドレスと同じか、それとも +1 でしょうか?
# foo のアドレス +2 すると bar のアドレスですよね
なんかアホなこと言っているようですみません。
メモリアドレス的に的確に伝えるには難しいような気が。。。
: baz foo ( ここ ) bar ( そこ ) ;
16bitアドレス環境として、スレデッドコードで考えると、
(ここ)は foo のアドレスと同じか、それとも +1 でしょうか?
# foo のアドレス +2 すると bar のアドレスですよね
なんかアホなこと言っているようですみません。
496デフォルトの名無しさん
2008/10/10(金) 00:55:01 >>495
「barのアドレス」と書くとbazの定義の中のbarの呼び出しのあるアドレスなのか、
それともbar自身の定義のアドレスなのか混乱するから、
( ここ ) と表現したわけで、その違いがわかってるなら問題ないですよん。
あとポインタってわかるよね?
「barのアドレス」と書くとbazの定義の中のbarの呼び出しのあるアドレスなのか、
それともbar自身の定義のアドレスなのか混乱するから、
( ここ ) と表現したわけで、その違いがわかってるなら問題ないですよん。
あとポインタってわかるよね?
497デフォルトの名無しさん
2008/10/10(金) 01:03:18498496
2008/10/10(金) 01:20:54499464
2008/10/10(金) 01:36:27 >498
新しいかどうかなんて知らんよ。単にWORDの扱いを正規化できてVMが簡素になるっつうだけの話。
>497で言及している(ここ)(そこ)みたいな間接ポインタをVMで扱う必要も無くなるし。
まあ、その皺寄せをWORDに押し込んでるだけなんだけどね。
新しいかどうかなんて知らんよ。単にWORDの扱いを正規化できてVMが簡素になるっつうだけの話。
>497で言及している(ここ)(そこ)みたいな間接ポインタをVMで扱う必要も無くなるし。
まあ、その皺寄せをWORDに押し込んでるだけなんだけどね。
500496
2008/10/10(金) 01:42:51 >>499
なんていうか…
「(ここ)(そこ)みたいな間接ポインタ」というそれそのものが、
アセンブリ言語の時代からある「リターンアドレス」という概念なんですよ…。
Forthはそれをリターンスタックに分離して保存・復帰しているだけのこと。
なんていうか…
「(ここ)(そこ)みたいな間接ポインタ」というそれそのものが、
アセンブリ言語の時代からある「リターンアドレス」という概念なんですよ…。
Forthはそれをリターンスタックに分離して保存・復帰しているだけのこと。
501デフォルトの名無しさん
2008/10/10(金) 06:35:09502デフォルトの名無しさん
2008/10/10(金) 08:32:35 >500
今は実際のリターンアドレスの話をしとらんよ。
リターンスタックを「次に実行する命令の列」という形に抽象化するっつうとるだろうに。
今は実際のリターンアドレスの話をしとらんよ。
リターンスタックを「次に実行する命令の列」という形に抽象化するっつうとるだろうに。
503デフォルトの名無しさん
2008/10/10(金) 08:46:05 >>501
." とか、 前付きの " は、Forthではただの引用符じゃなくて、一つのワード。
だから、Helloとの間に空白が要る。
但し、終わりの " はセパレーターだから、空白なしで良い。
前にも出てたけど、
Forthでは文字列リテラルはポインタと長さの二つの数値で表す。
「.」は、トップアイテムを一つpopして値をプリントするワードだから、
" Hello" .
だと5がプリントされるだけ。文字列ポインタがスタックに残る。
「."」 が 「次の " までの文字列をプリントする」というワード。
文字列をスタックに積んだときは
" Hello" type
とやる。
." とか、 前付きの " は、Forthではただの引用符じゃなくて、一つのワード。
だから、Helloとの間に空白が要る。
但し、終わりの " はセパレーターだから、空白なしで良い。
前にも出てたけど、
Forthでは文字列リテラルはポインタと長さの二つの数値で表す。
「.」は、トップアイテムを一つpopして値をプリントするワードだから、
" Hello" .
だと5がプリントされるだけ。文字列ポインタがスタックに残る。
「."」 が 「次の " までの文字列をプリントする」というワード。
文字列をスタックに積んだときは
" Hello" type
とやる。
504デフォルトの名無しさん
2008/10/10(金) 08:52:55 >>502
だから、「次に実行する命令列」は辞書の中に既にあるんであって、
それはスタックである必要はなくて、いってみればアレイ。
辞書の中で実行は動的に行ったり戻ったりするから、
やっぱりリターンアドレスの保存は必要。
だから、「次に実行する命令列」は辞書の中に既にあるんであって、
それはスタックである必要はなくて、いってみればアレイ。
辞書の中で実行は動的に行ったり戻ったりするから、
やっぱりリターンアドレスの保存は必要。
505デフォルトの名無しさん
2008/10/10(金) 09:06:11506デフォルトの名無しさん
2008/10/10(金) 17:24:55 factorだと文字列リテラルはあるよ
507488
2008/10/10(金) 22:08:31 >>496,497 サンクス
スレデッドコードと書いておいて誤解がなかったようだ。
497 のレスだと、俺の中では「次のワード」という認識になる。
(あっち)という表現を使えば確かに誤解はなくなる。
なんだか、リターンスタックのデータ内容と、
(サブルーチン)リターンアドレスを混同した希ガス
スレデッドコードと書いておいて誤解がなかったようだ。
497 のレスだと、俺の中では「次のワード」という認識になる。
(あっち)という表現を使えば確かに誤解はなくなる。
なんだか、リターンスタックのデータ内容と、
(サブルーチン)リターンアドレスを混同した希ガス
508464
2008/10/11(土) 00:37:41 >504
「必要がないから積まない」じゃなくて、「VMの原理を簡単にするために積む」んだって。
VMが辞書の中を行ったり来たりしないようにするのが目的。
もちろん、VMの仕事をWORDに移管しただけの話だし、スタックが大きくなるデメリットもあるけどな。
「必要がないから積まない」じゃなくて、「VMの原理を簡単にするために積む」んだって。
VMが辞書の中を行ったり来たりしないようにするのが目的。
もちろん、VMの仕事をWORDに移管しただけの話だし、スタックが大きくなるデメリットもあるけどな。
509504
2008/10/11(土) 01:03:24 >>508
つまり、ワードを全部インラインにするということ?
それなら確かに理論的には可能だし、リターンスタック自体要らない。
普通は、大きくなるのはスタックじゃなくて辞書だな。
まあ、辞書からインラインで展開したものを
リターンスタックにコピーしてもいいけど、
ランタイムにやるなら相当動作が遅くなると思う。
それに、
なぜそのためにスタックというデータ構造を使うのかがわからない。
後ろから先に積んでいくことになるわけだが。
その発想はインストラクションキャッシュだと思う。
だから、むしろキューがいいと思う。
ソフトウェア的にやると相当遅いとは思うけど、
論理的には可能だと思うよ。
つまり、ワードを全部インラインにするということ?
それなら確かに理論的には可能だし、リターンスタック自体要らない。
普通は、大きくなるのはスタックじゃなくて辞書だな。
まあ、辞書からインラインで展開したものを
リターンスタックにコピーしてもいいけど、
ランタイムにやるなら相当動作が遅くなると思う。
それに、
なぜそのためにスタックというデータ構造を使うのかがわからない。
後ろから先に積んでいくことになるわけだが。
その発想はインストラクションキャッシュだと思う。
だから、むしろキューがいいと思う。
ソフトウェア的にやると相当遅いとは思うけど、
論理的には可能だと思うよ。
510デフォルトの名無しさん
2008/10/11(土) 02:00:15 サンクス >693
5 ソースコード
6 boost::spirit
というので激しく不安になるな。
というか、スクリプトの入門というのなら、BASICタイプ言語の作成とかCタイプ言語の作成
とか分散しないで、どっちか一つに集中すべきじゃない?
入門だったら、むしろ構文はシンプルなforthライクにして、エンジンの中身に拘るべきだと思うけど……
5 ソースコード
6 boost::spirit
というので激しく不安になるな。
というか、スクリプトの入門というのなら、BASICタイプ言語の作成とかCタイプ言語の作成
とか分散しないで、どっちか一つに集中すべきじゃない?
入門だったら、むしろ構文はシンプルなforthライクにして、エンジンの中身に拘るべきだと思うけど……
511デフォルトの名無しさん
2008/10/11(土) 02:02:28 誤爆スマソ
512464
2008/10/11(土) 02:18:22 >509
いや、基本はWORD呼び出し時に展開(そのWORDに定義されたWORD列をスタックに押し込む)。
WORDコンパイル時に全部インラインに展開するわけじゃないです。
#高速化を目的として、WORDコンパイル時にある程度はインライン化することになると思うけど。
WORDに定義されたWORD列を、実行時にその場で積んでその場で処理する必要があるから、
FIFOの仕組みが必要になります。
まあ、小まめにWORDの積み降ろしをやらなきゃいけないから、確かに重そうだけどね。
いや、基本はWORD呼び出し時に展開(そのWORDに定義されたWORD列をスタックに押し込む)。
WORDコンパイル時に全部インラインに展開するわけじゃないです。
#高速化を目的として、WORDコンパイル時にある程度はインライン化することになると思うけど。
WORDに定義されたWORD列を、実行時にその場で積んでその場で処理する必要があるから、
FIFOの仕組みが必要になります。
まあ、小まめにWORDの積み降ろしをやらなきゃいけないから、確かに重そうだけどね。
513デフォルトの名無しさん
2008/10/11(土) 05:37:05 464のやり方は、ありえなくはないけどForth的じゃないね。
どっちかっていうとJava VMのJITコンパイラみたいな。
Forthはシンプルな実装で軽い、ってイメージ。
どっちかっていうとJava VMのJITコンパイラみたいな。
Forthはシンプルな実装で軽い、ってイメージ。
514デフォルトの名無しさん
2008/10/11(土) 06:54:12515464
2008/10/11(土) 13:07:00 >513
いや、実装はこっちの方がシンプルだよ。辞書の解釈を全部WORDに押し付けることができるから。
ただ、スタック操作が増えるから重くなる方向だけどね。
>514
リターンアドレス前提だと難しいよね。作業用スタックがもう一本ありゃいいんだけど。
俺言語のVMだと自前スタックで実装しているので大した話じゃないです。
いや、実装はこっちの方がシンプルだよ。辞書の解釈を全部WORDに押し付けることができるから。
ただ、スタック操作が増えるから重くなる方向だけどね。
>514
リターンアドレス前提だと難しいよね。作業用スタックがもう一本ありゃいいんだけど。
俺言語のVMだと自前スタックで実装しているので大した話じゃないです。
516464
2008/10/11(土) 13:22:12 >514
ちょっと補足。
複数のWORDを押し込もうとすると確かに面倒だね。
俺言語でも
1. 無名WORDを作る
2. 1.のWORDに実行するWORDを押し込む
3. 1.のWORDをリターンスタックに押し込む
といったパック化が必要になります。
ちょっと補足。
複数のWORDを押し込もうとすると確かに面倒だね。
俺言語でも
1. 無名WORDを作る
2. 1.のWORDに実行するWORDを押し込む
3. 1.のWORDをリターンスタックに押し込む
といったパック化が必要になります。
517デフォルトの名無しさん
2008/10/11(土) 13:26:05 464のVMだが、
ハードウェアレベルではもう一般化してる
インストラクションのプリフェッチとおなじだよね。
マシン語のデコーダレベルでのVMという感じか。
実装する場合の最難題は条件付きジャンプだと思う。
IFとか不定ループをどう載せるかが鍵だな。
これを考えると、VMが仕組みとして単純になるかどうかは微妙だと思う。
まあ、ベタでやればできそうな気はするが、
ハードウエアの仕組みをソフトウェアで二重にしてるだけのような気がしないでもない。
ハードウェアレベルではもう一般化してる
インストラクションのプリフェッチとおなじだよね。
マシン語のデコーダレベルでのVMという感じか。
実装する場合の最難題は条件付きジャンプだと思う。
IFとか不定ループをどう載せるかが鍵だな。
これを考えると、VMが仕組みとして単純になるかどうかは微妙だと思う。
まあ、ベタでやればできそうな気はするが、
ハードウエアの仕組みをソフトウェアで二重にしてるだけのような気がしないでもない。
518464
2008/10/11(土) 13:38:04 >514
思い出した……>59を実現するにはreverse自体のパック化も必須なんだっけ。
そういや>59みたいな操作をどうしようか悩んだな。
ただ、こういったWORDを跨ぐ暗黙的なリターンスタック制御てけっこう危険じゃない?
個人的にはWORDはデータスタックの状態にのみ依存すべきだと思うけど、WORDを越えた
範囲までリターンスタックを操作できるようにすると、WORD同士の依存関係が出てしまって
連鎖性(concatenative)が崩れるような気がする。
forthの条件分岐でも、セパレーターを使った明示的な制御をしているわけだし。
思い出した……>59を実現するにはreverse自体のパック化も必須なんだっけ。
そういや>59みたいな操作をどうしようか悩んだな。
ただ、こういったWORDを跨ぐ暗黙的なリターンスタック制御てけっこう危険じゃない?
個人的にはWORDはデータスタックの状態にのみ依存すべきだと思うけど、WORDを越えた
範囲までリターンスタックを操作できるようにすると、WORD同士の依存関係が出てしまって
連鎖性(concatenative)が崩れるような気がする。
forthの条件分岐でも、セパレーターを使った明示的な制御をしているわけだし。
519464
2008/10/11(土) 13:49:31 連投スマソ
>517
そうか、CPUだともう一般的なのか……。さすがに天才的な変態が集まる業界だな。
やっぱりCPUのアーキテクチャ勉強しないといけないなあ。
IFは構文解析で逃げました。
block := block ? WORD1 ! WORD2
という三項演算子を用意して、条件分岐用WORDに解釈するようにしました。
不定ループの構文を用意するかどうかは検討中です。
>517
そうか、CPUだともう一般的なのか……。さすがに天才的な変態が集まる業界だな。
やっぱりCPUのアーキテクチャ勉強しないといけないなあ。
IFは構文解析で逃げました。
block := block ? WORD1 ! WORD2
という三項演算子を用意して、条件分岐用WORDに解釈するようにしました。
不定ループの構文を用意するかどうかは検討中です。
520517
2008/10/11(土) 13:59:32 もうすこし考えてみたんだが、
ワードがどこかで他のワードを呼び出し、そのワードがどこかで他のワードを呼出し...
という場合には、
ワードシーケンスに展開する段階で、
展開すべき個所をたどるためのリターンスタックが必要な気がする。
だから、464のVMは、
普通のForthでの実行と同じ動作でワード系列をコピーして、
それから順番にInterpretして実行するという感じになって、
単なる二度手間ではないかな。
ワードがどこかで他のワードを呼び出し、そのワードがどこかで他のワードを呼出し...
という場合には、
ワードシーケンスに展開する段階で、
展開すべき個所をたどるためのリターンスタックが必要な気がする。
だから、464のVMは、
普通のForthでの実行と同じ動作でワード系列をコピーして、
それから順番にInterpretして実行するという感じになって、
単なる二度手間ではないかな。
レスを投稿する
ニュース
- 橋下徹氏 外務省幹部の訪中受け「口だけ番長」へ痛烈指摘 「喧嘩は日本の完敗…なんとかっこ悪い日本か」 [冬月記者★]
- 【外国人問題】小野田紀美担当相「不法就労や不法滞在は許さない」 [シャチ★]
- 【野球】井端監督 大谷翔平、山本由伸らのWBCへの参加 「1日も早く返事ほしい」「待っててといっても、国内組が遅くなってしまう」★3 [冬月記者★]
- 経団連会長、日中は建設的対話を 経済3団体が高市首相と初会談も日中関係は話題に登らず… [BFU★]
- 中国で「クレしん」公開延期 対日報復、エンタメに波及 [蚤の市★]
- 東京株式市場 インバウンド関連株が下落 中国政府の渡航自粛要請で [バイト歴50年★]
- 🏡
- スーパーが開くまで約4時間何すりゃいいんだ?
- 有識者「高市総理が発言を撤回したり、辞職するしかないと言っている人は、それで日中関係が今まで通りになると思ってる?」 [834922174]
- 飲みの約束だるい
- 減税は低所得者差別
- 高市さんに土下座してもらったら一発解決なのに何でやらないんだろ??
