2012-01-01 18 views
5

Intenté implementar una palabra que produce una cadena de una matriz cuando se le da un número en la pila en Forth.¿Cómo implemento una matriz de cadenas?

Mi primer intento fue ingenua:

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

Esto fue aceptado, pero que no funcionó como se esperaba - myarray @ type produce una salida inconsistentes (en lugar de mi ingenua esperanza de que podría imprimir "alfa").

Al buscar en la web, encontré en this tutorial que una cadena creada con s" tiene una vida útil limitada, lo que significa que mi ansatz está destinada a fallar desde el principio. Por otro lado, incluso las matrices de objetos regulares parecen no estar estandarizadas de acuerdo con this page.

< Actualización> Aparentemente, esto no es un problema trivial con Forth. Hay bibliotecas en la web que implementan la funcionalidad de cadena faltante: here y here. Este es un buen punto de partida, aunque todavía requiere trabajo para ir desde allí a una serie de cadenas. </Update>

Entonces, ¿cómo puedo implementar una palabra que devuelve una cadena de una matriz determinada?

Respuesta

2

Para direccionar partes de su código, s" deja addr u en la pila, una dirección y la longitud de la cadena. , solo almacena un valor para que no obtenga los resultados deseados de esa manera. 2, podría hacerlo ya que eso almacenaría ambos elementos de la pila que representan la cadena. Una vez que haya hecho eso, necesita recuperar ambos valores para que [email protected] sea lo que desea.

Mi reescritura se vería así:

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

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

Conseguir a los otros elementos de la matriz es un poco más complicado. Cuando escribe myarray, obtiene la dirección del inicio de los datos en esa entrada del diccionario, y luego puede usar 2 @ para obtener las cosas a las que apuntan las dos primeras direcciones (que son la dirección y la longitud de "Alpha") . Si quieres "Beta se necesita el siguiente par de direcciones. Así que usted puede utilizar

myarray 2 cells + \ increment the address by two cells 

Para obtener las direcciones que apuntan a 'Beta' y así sucesivamente. Así que con el fin de acceder a 'Beta' debe presionar

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

he probado esto con gforth y parece que todo el trabajo, aunque no estoy seguro de cómo poner a prueba rigurosamente para la persistencia.

Su palabra tendría que ser capaz de hacer la dirección de incrementar basa en lo está en la pila para empezar. Es posible que desee entrar en más create does> cosas. Puedo dar algunos consejos, pero no quiero estropear la diversión del descubrimiento.

Si me salteo demasiados detalles de lo que esto significa en realidad solo digo, y lo intentaré de nuevo.


Tal vez esto es demasiado crudo, pero tuve un intento de hacer una especie de "tipo de cuerda" hace un tiempo.

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

Se define una palabra con un nombre de su elección (en este caso "palabras") que impulsará la longitud y dirección inicial de la cadena (en este caso "algunas palabras") cuando se interpreta. Hasta donde yo sé, cuando la cadena está en una definición como esta, es persistente.

Esto no le responde completamente la pregunta, pero podría ayudar.


he tenido otra oportunidad en una cadena persistente, este definitivamente allot s memoria dentro de una entrada de diccionario y estará a salvo, mientras exista esa palabra. Antes de la cadena "tipo" solo se almacenaba la dirección y la longitud que se creó s" que solo sirve para nada hasta que otra cosa escriba sobre esa región de la memoria. Esto ahora copia la cadena desde donde s" lo crea en un elemento del diccionario llamado "nombre" donde se garantiza que durará tanto como el "nombre".

: 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 

Para la diversión, pensé que podría mostrar cómo poco sentido esto hace sin formato útil

: 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

En realidad, puedo seguir hasta el punto en que comentario sobre "CREATE hace>' cosas". Tendré que cavar más profundo para comprender también el resto. Aparte de eso, creo que resolvió mi problema (con la posible cuestión abierta de persistencia que está claramente mal documentada en el manual de GForth). ¡Gracias! – user8472

+0

Sí, eso fue bastante vago, básicamente no estaba seguro de cómo hacerlo sin pensarlo por un tiempo. Parece que cualquier cosa en una definición es persistente (eso es lo que tomé del manual). – sheepez

+0

@ user8472 Solo quería avisarte de mis ediciones, la nueva versión definitivamente es persistente. – sheepez

Cuestiones relacionadas