2012-01-01 41 views
5

Tôi đã cố gắng thực hiện một từ tạo ra một chuỗi từ một mảng khi đưa ra một số trên ngăn xếp trong Forth.Làm cách nào để triển khai một chuỗi các chuỗi?

nỗ lực ngây thơ đầu tiên của tôi là:

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

này đã được chấp nhận, nhưng nó đã không làm việc như mong đợi - myarray @ type sản lượng sản xuất không phù hợp (thay vì kỳ vọng ngây thơ của tôi rằng nó có thể in "Alpha").

Khi tìm kiếm trên web, tôi tìm thấy trong this tutorial rằng chuỗi được tạo với s" có thời lượng giới hạn có nghĩa là ansatz của tôi bị ràng buộc không thành công ngay từ đầu. Mặt khác, ngay cả các mảng đối tượng thông thường dường như không được tiêu chuẩn hóa theo this page.

< Cập nhật> Rõ ràng, đây không phải là vấn đề tầm thường với Forth. Có các thư viện trên web triển khai chức năng thiếu chuỗi: herehere. Đây là một điểm khởi đầu tốt, mặc dù nó vẫn đòi hỏi công việc phải đi từ đó đến một chuỗi các chuỗi. </Cập nhật>

Vậy làm cách nào để triển khai một từ trả về chuỗi từ một mảng nhất định?

Trả lời

2

Để giải quyết các phần mã của bạn, s"addr u trên ngăn xếp, địa chỉ và độ dài của chuỗi. , chỉ lưu trữ một giá trị để bạn không nhận được kết quả mong muốn theo cách đó. 2, có thể làm như vậy sẽ lưu trữ cả hai mục ngăn xếp đại diện cho chuỗi. Một khi bạn đã làm điều đó bạn cần phải có được cả hai giá trị trở lại quá [email protected] là những gì bạn muốn.

viết lại của tôi sẽ giống như thế này:

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

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

Bắt tại các yếu tố khác của mảng của bạn là một chút phức tạp hơn. Khi bạn nhập myarray bạn nhận được địa chỉ bắt đầu dữ liệu trong mục nhập từ điển đó và sau đó bạn có thể sử dụng 2 @ để nhận được những thứ mà hai địa chỉ đầu tiên trỏ đến (đó là địa chỉ và độ dài của "Alpha") . Nếu bạn muốn "Beta bạn cần cặp tiếp theo địa chỉ. Vì vậy, bạn có thể sử dụng

myarray 2 cells + \ increment the address by two cells 

Để có được địa chỉ điểm đến 'Beta' và như vậy. Vì vậy, để truy cập vào 'Beta' bạn sẽ nhập

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

tôi đã thử nghiệm này với gforth và có vẻ như tất cả công việc, mặc dù tôi không chắc chắn làm thế nào để một cách nghiêm ngặt kiểm tra cho persistence.

lời của bạn sẽ cần để có thể làm địa chỉ incrementing dựa trên những gì đang ở trên ngăn xếp để bắt đầu. Bạn có thể muốn tham gia vào một số chi tiết create does> nội dung. Tôi có thể đưa ra một số gợi ý nhưng tôi không muốn làm hỏng niềm vui khám phá.

Nếu tôi bỏ qua quá nhiều chi tiết về điều này thực sự có nghĩa là chỉ cần nói và tôi sẽ thử lại.


Có thể điều này quá thô, nhưng tôi đã thực hiện một loại "kiểu chuỗi" trước đây.

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

Nó định nghĩa một từ với một tên lựa chọn của bạn (trong trường hợp này "chữ") mà sẽ đẩy chiều dài và bắt đầu địa chỉ của chuỗi của bạn (trong trường hợp này "một số từ") khi nó được giải thích. Theo như tôi biết khi chuỗi là trong một định nghĩa như thế này nó là dai dẳng.

Điều này không trả lời bạn đầy đủ, nhưng có thể hữu ích.


Tôi đã có một đi vào một chuỗi dai dẳng, điều này chắc chắn nhớ allot s trong một mục từ điển và sẽ được an toàn miễn là từ đó tồn tại. Trước khi chuỗi "loại" chỉ được lưu trữ địa chỉ và độ dài mà s" tạo ra mà chỉ là bất kỳ tốt cho đến khi một cái gì đó khác viết trên khu vực đó của bộ nhớ. Điều này bây giờ sao chép các chuỗi từ nơi s" tạo nó thành một mục từ điển gọi là "tên", nơi nó được đảm bảo để kéo dài miễn là "tên" chính nó.

: 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 

Đối với giải trí, tôi nghĩ rằng tôi có thể hiển thị như thế nào ít cảm giác này làm cho không có định dạng hữu ích

: 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

Thực ra, tôi có thể làm theo cho đến điểm mà bạn nhận xét về "' tạo các không> ' đồ đạc". Tôi sẽ cần đào sâu hơn để hiểu phần còn lại của nó. Ngoài ra, tôi nghĩ rằng bạn đã giải quyết được vấn đề của mình (với vấn đề tồn tại có thể có của sự kiên trì rõ ràng đã được ghi lại trong tài liệu hướng dẫn của GForth). Cảm ơn bạn! – user8472

+0

Vâng, điều đó khá mơ hồ, về cơ bản tôi đã không chắc chắn làm thế nào để làm điều đó mà không cần suy nghĩ về nó trong một thời gian. Có vẻ như bất cứ điều gì trong một định nghĩa là dai dẳng (đó là những gì tôi đã lấy từ hướng dẫn). – sheepez

+0

@ user8472 Tôi chỉ muốn cảnh báo bạn về các chỉnh sửa của tôi, phiên bản mới chắc chắn là liên tục. – sheepez

Các vấn đề liên quan