lunes, 26 de febrero de 2024

Estructuras de control: implementación del IF

 La J1s tiene una sola instrucción de salto condicional: 0branch direccion.

Es una instrucción simple: si el tope del stack es cero, la ejecución sigue en la dirección indicada. En cualquier caso, el tope del stack es descartado.

Por otra parte, Forth tiene el IF-ELSE-THEN. Si el tope del stack es distinto de cero, se ejecutan las instrucciones entre el IF y el ELSE.  Si el stack es cero, se ejecutan las instrucciones entre el ELSE y el THEN. Por supuesto, el bloque else es opcional.

La instrucción IF siempre remueve el tope del stack.

Veamos, por ejemplo, la definición de la función lógica NOT: si el tope del stack es cero, se reemplaza por un uno. En caso contrario, se reemplaza con cero.

: not if 0 else 1 then ;

La implementación del IF-THEN-ELSE es

0branch bloque-else
    ... instrucciones caso Verdadero
    jmp outside
bloque-else:
    ... instrucciones caso Falso
outside:          ; Siguiente instrucción


que para este ejemplo sería

Dir  Código   Instrucción
03b1 23b4     0branch b-else   ; Comienza NOT
03b2 8000     0                ; Coloca un cero en el stack
03b3 03b5     jmp b-then
         b-else:
03b4 8001     1                ; Coloca un uno en el stack.
         b-then: 
03b5 608c     ret              ; Retorno (fin de la implementación)

El IF sólo puede ser usado en la definición de una palabra; no en forma interactiva. Por lo tanto, el interprete se encuentra con ella mientras está en modo compilación, sin saber que viene por delante. En esta fase, el compilador va generando las instrucciones de máquina en memoria. Una vez terminada la compilación, el código será ingresado al diccionario Forth.

Al ver el IF, el compilador genera una instrucción 0branch 0, dado que aun no se conoce la dirección de destino.

Cuando encuentra un ELSE, inserta un jmp 0 para saltar sobre las instrucciones que vienen a continuación.

Al encontrarse con ELSE/THEN, el compilador busca atrás en memoria la instrucción 0branch 0 y la parcha con la dirección de la próxima instrucción. Si encuentra un jmp 0, también lo parcha con la misma dirección.

Asi podemos compilar el IF-ELSE-THEN sin necesidad de variables intermedias.


No hay comentarios.:

Publicar un comentario