2012-01-01 17 views
5

Próbowałem zaimplementować słowo, które tworzy łańcuch z tablicy po podaniu numeru na stosie w Forth.Jak zaimplementować tablicę łańcuchów?

Moja pierwsza próba była naiwna:

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

ten został przyjęty, ale to nie działa zgodnie z oczekiwaniami - myarray @ type produkuje wyjście niespójne (zamiast mojej naiwnej nadziei, że może go wydrukować „alpha”).

Podczas wyszukiwania w Internecie, znalazłem w this tutorial, że ciąg znaków utworzony za pomocą s" ma ograniczony czas życia, co oznacza, że ​​mój ansatz od początku nie działa. Z drugiej strony, nawet tablice zwykłych obiektów wydają się nie być wystandaryzowane zgodnie z this page.

Aktualizacja> Wygląda na to, że nie jest to banalny problem z Forth. Istnieją biblioteki w Internecie, które implementują brakujące funkcje łańcuchowe: here i here. To dobry punkt wyjścia, chociaż nadal wymaga pracy, aby przejść stamtąd do tablicy łańcuchów. /Aktualizacja>

Jak mogę zaimplementować słowo, które zwraca ciąg znaków z danej tablicy?

Odpowiedz

2

Aby zaadresować części kodu, s" pozostawia na stosie numer addr u, adres i długość ciągu. , przechowuje tylko jedną wartość, więc nie uzyskasz pożądanych rezultatów w ten sposób. 2, może to zrobić, ponieważ będzie przechowywać oba elementy stosu, które reprezentują ciąg znaków. Gdy już to zrobisz, musisz odzyskać obie wartości, aby [email protected] było tym, czego potrzebujesz.

Moja przepisać będzie wyglądać następująco:

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

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

dojazd na pozostałych elementów macierzy jest nieco trudniejsze. Po wpisaniu myarray otrzymasz adres początku danych w tym wpisie słownikowym, a następnie możesz użyć 2 @, aby uzyskać rzeczy, na które wskazują dwa pierwsze adresy (które są adresem i długością "Alfa") . Jeśli chcesz „Beta trzeba następną parę adresów. Więc można użyć

myarray 2 cells + \ increment the address by two cells 

Aby uzyskać adresy tego punktu do«beta»i tak dalej. Tak więc w celu uzyskania dostępu do«Beta», należy wprowadzić

myarray 2 cells + [email protected] type Beta **ok** 

ja testowałem to z gforth i wydaje się, aby wszystkie prace, choć nie jestem pewien, jak rygorystycznie przetestować za wytrwałość.

Twoje słowo musiałoby być w stanie wykonać adres zwiększając w oparciu o jakie jest na stosie na początek. Możesz chcieć uzyskać więcej create does> rzeczy. Mogę podać kilka wskazówek, ale nie chcę popsuć zabawy odkrywania.

Jeśli pomijam zbyt wiele szczegółów tego, co to właściwie oznacza po prostu powiedz, a spróbuję ponownie.


Być może jest to zbyt prymitywne, ale musiałem przejść do tworzenia pewnego rodzaju "stringów" jakiś czas temu.

: 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** 

Definiuje słowo z nazwy swojego wyboru (w tym przypadku „słowa”), które będą wymuszać długości i zaczynają adres swojego łańcucha (w tym przypadku „kilka słów”), gdy jest on interpretowany. O ile wiem, kiedy ciąg jest w definicji takiej jak ta, jest trwały.

To nie odpowie na wszystkie Twoje pytania, ale może pomóc.


miałem inne odchodzenie na trwałe łańcucha, ten na pewno allot s pamięć wewnątrz słownika wpisu i będzie bezpieczny, dopóki istnieje to słowo. Przed ciągiem "typ" zapisywano tylko adres i długość, które zostały utworzone, co jest tylko dobrym, dopóki coś innego nie zapisze w tym obszarze pamięci. Teraz kopiuje ciąg znaków, skąd s" tworzy go w słowniku o nazwie "nazwa", na którym gwarantuje się, że będzie trwał tak długo jak sama nazwa.

: 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 

dla zabawy, myślałem że mogę pokazać, jak niewiele sensu To sprawia, że ​​bez pomocnego formatowania

: 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

Właściwie mogę podążać aż do punktu, w którym to skomentować „' create robi> ' rzeczy". Będę musiał głębiej zagłębić się, aby zrozumieć resztę. Poza tym myślę, że rozwiązałeś mój problem (z możliwym otwartym problemem trwałości, który jest wyraźnie źle udokumentowany w podręczniku GForth). Dziękuję Ci! – user8472

+0

Tak, to było dość ogólnikowe, w zasadzie nie byłem pewien, jak to zrobić, nie myśląc o tym przez chwilę. Wydaje się, że wszystko w definicji jest trwałe (to właśnie wziąłem z podręcznika). – sheepez

+0

@ user8472 Po prostu chciałem powiadomić cię o moich zmianach, nowa wersja jest zdecydowanie trwała. – sheepez

Powiązane problemy