28 agosto 2008

Un compilador sencillo paso a paso (15 - Pequeñas mejoras)

Nuestro analizador léxico tiene todavía varias carencias. Posiblemente una de las más importantes es que los identificadores pueden estar formados por varias letras, pero los operadores no, por lo que todavía no podemos reconocer comparaciones como "<=".

Para solucionarlo, tenemos dos alternativas. La rápida pero mala es permitir que los "símbolos" estén formados por más de un carácter. La correcta es empezar a hablar (por fin) de "tokens". Así, tanto "if" como "+" o "<=" o la variable "x" serían tokens, cada uno de ellos con un "valor" o "lexema" y también con un "tipo" (junto con otros datos que nos pueden ser útiles, como la fila y columna en que se encuentra). Esta estructura estaba preparada desde la versión 0.07, pero no la habíamos utilizado hasta ahora.

Además aprovecharemos para corregir las asignaciones: los símbolos ":=" podían estar separados, por lo que hasta ahora ": =" se habría interpretado como una asignación válida. Nos vendrá bien usar, además de la función "leerCaracter" otra "devolverCaracter" que será necesaria cuando leamos de más al comprobar si al ":" le sigue un "=".

Además, orientado a la máquina de destino añadiremos una orden cpcInk, que permita jugar con la paleta de colores, redefinir color haciendo cpcInk(1,WHITE); o bien cpcInk(1,BLUE, RED); (este último formato parpadearía entre dos colores). Estas constantes para los colores estarán definidas también en el compilador, para que el código sea más legible. También añadiremos una orden WriteString, que escriba una cadena (prefijada) en vez de sólo una letra.

Ahora podremos hacer cosas como:

program ej15; { Ejemplo 15 de CpcPaChi }

var
i, j, k: byte;

procedure inicializa;
begin
cpcMode (1);
cpcInk(0,BLACK);
cpcInk(1,WHITE);
cpcInk(2,BRIGHTYELLOW);
cpcInk(3,PALEYELLOW);
paper(0);
end;

procedure lineaHorizontal;
begin
for i := 1 to 10 do
writeChar('*') ;
end;

(* Vamos a dibujar un cuadrado *)
begin

inicializa;
locate(2,2);
writeString('Alla vamos...');

locate(10,3);
pen(1);
lineaHorizontal;

pen(2);
for j := 4 to 7 do
begin
locate(10,j);
writeChar('*');
for k := 1 to 8 do
writeChar(' ');
writeChar('*');
end;

locate(10,8);
pen(3);
lineaHorizontal;

locate(20,20);
writeString('Hemos terminado!');
pen(1);
end.


Como siempre, para más detalles, todo el código está en la página del proyecto en Google Code:

http://code.google.com/p/cpcpachi/