2012-01-01 5 views
5

私は、Forthでスタック上の数字が与えられたときに配列から文字列を生成する単語を実装しようとしました。文字列の配列を実装するにはどうすればよいですか?

create myarray s" Alpha", s" Beta", s" Charlie", 

はこれが受け入れられたが、期待どおりに動作しませんでした - myarray @ typeは、一貫性のない出力を生成します(代わりに、それは「アルファ」を印刷するかもしれないというのが私の素朴な期待):

私の最初の素朴な試みでした。

this tutorialでウェブを検索すると、s"で作成された文字列の寿命が限られていることがわかりました。これは、私のansatzが最初から失敗することを意味しています。一方、普通のオブジェクトの配列さえも、this pageに従って標準化されていないようです。

<更新>明らかに、これはForthの問題ではありません。不足している文字列機能を実装するライブラリには、herehereがあります。これは良い出発点ですが、まだそこから一連の文字列に進む必要があります。 < /更新>

どのようにして、指定された配列から文字列を返す単語を実装できますか?

答えて

2

コードの一部に対処するには、s"をスタックに残して、アドレスと文字列の長さを設定します。 ,には1つの値しか格納されていないため、そのような結果は得られません。 2,は、文字列を表すスタック項目の両方を格納するので、これを行う可能性があります。これを済ませたら、両方の値を戻す必要がありますので、[email protected]があなたの望むものです。

私の書き換えは次のようになります。あなたの配列の他の要素で取得

create myarray s" Alpha" 2, s" Beta" 2, s" Charlie" 2, 

\ Test 
myarray [email protected] type Alpha **ok** 

は少しトリッキーです。 myarrayと入力すると、その辞書エントリのデータの開始アドレスが取得され、2 @を使用して最初の2つのアドレスが指しているもの(「Alpha」のアドレスと長さ)を取得できます。あなたがしたい場合は、「ベータあなたはアドレスの次のペアを必要としています。あなたはアドレスにそのポイントに到達するために

myarray 2 cells + \ increment the address by two cells 

を使用することができますので、 『ベータ版』とのように。アクセスするためにいわゆる 『ベータ版』あなたは

を入力します。
myarray 2 cells + [email protected] type Beta **ok** 

私はGforthのでこれをテストしていると私は厳密に永続化をテストする方法がわからないですが、それは、すべての作業に思える。

あなたの言葉は何に基づいてアドレスインクリメントを行うことができるようにする必要がありますスタックで始まっています。あなたはもっともっと入りたいかもしれません。create does>もの。私はいくつかの指摘をすることができますが、私は発見の楽しさを台無しにしたくありません。

もし私が実際に何を言っているのかということについてあまりに多くの詳細をスキップしているなら、私はもう一度やり直します。


これはあまりにも粗すぎるかもしれませんが、私はしばらく前に「文字列タイプ」を作っていました。

: string         (addr u "name" --) 
    create 2,        \ add address and length to dict entry "name" 
    does> dup cell+ @ swap @ ;    \ push addr u 

\ Example 
s" Some Words" string words **ok** 
word type Some Words **ok** 

それが解釈されたときには(この場合は「いくつかの単語」)の長さをプッシュし、あなたの文字列のアドレスを開始します(「言葉」は、この場合には)お好みの名前と言葉を定義します。私が知る限り、文字列がこのような定義にあるときは永続的です。

これはあなたの質問に完全には答えませんが、役立つかもしれません。


私は、別の永続的な文字列で行くこれは間違いなく1の辞書のエントリ内allot sのメモリを持っていると、その単語が存在する限り、安全になります。文字列 "type"の前には、s"が作成したアドレスと長さだけが格納されています。これは、何か他のものがメモリのその領域に書き込むまで有効です。これで、s"が作成する文字列が "name"という辞書項目にコピーされます。この項目では、 "name"自体の長さが保証されます。アミューズメント用

: string         (addr u "name" --) 
    create         \ create dict entry called "name" 
    dup >r here >r       \ keep copies of string length and start of "name"'s memory 
    dup 2 cells + allot      \ allot memory for the number of chars/bytes of the string plus 2 
              \ for the new addr u 
    [email protected] 2 cells +       \ Get the address two cells from the start the space for "name" 
    swap cmove        \ copy the string at addr u into the alloted space for "name" 

    \ Now "name" looks like this: "name" -blank1- -blank2- "the text of the string at addr u" 
    \ blank1 should be the address of the start of the the text = addr2 and blank2 should be u 

    [email protected] dup 2 cells + swap !     \ get the address of blank1, copy it, increment by 2 to get addr2 
              \ and then store that in blank1 
    r> cell+ r> swap !      \ get address of blank1, increment to get address of blank2, then get u and 
              \ store it in blank2 

    \ Now "name" looks like this: "name" addr2 u "the text of the string at addr u" 

    does> dup @ swap cell+ @ ;    \ push addr2 u 

、私は実際に、私が ``>ん作成」あなたは上のコメントの点まで続くことができる私は、これは

: string-no-comments   (addr u "name" --) 
    create dup >r here >r dup 2 cells + allot [email protected] 
    2 cells + swap cmove [email protected] dup 2 cells + swap ! 
    r> cell+ r> swap ! does> dup @ swap cell+ @ ; 
+1

役立つフォーマットせずに作る方法をほとんど意味を示しかもしれないと思いましたもの "。残りの部分を理解するために、さらに深く掘り下げる必要があります。それとは別に、私はあなたが私の問題を解決したと思います(GForthのマニュアルにはっきりと記載されている永続性の問題があります)。ありがとうございました! – user8472

+0

それはかなり曖昧だった、基本的に私はしばらくそれを考えずにそれを行う方法がわからなかった。定義の中の何かが永続的であると思われます(それは私がマニュアルから取ったものです)。 – sheepez

+0

@ user8472私はちょうど私の編集にあなたに警告したい、新しいバージョンは間違いなく永続的です。 – sheepez