Comprobación de Tipos: Las Expresiones

La comprobación de tipos la haremos expandiendo nuestro programa árbol con nuevas transformaciones para cada uno de los tipos de nodos.

Expresiones Binarias

Las operaciones binarias requieren que sus operandos sean de tipo entero. Si el tipo de alguno de los operandos es CHAR haremos una conversión explícita al tipo INT (líneas 17-18):

nereida:~/doc/casiano/PLBOOK/PLBOOK/code/Simple-Types/lib/Simple> sed -ne '66,90p' Trans.trg | cat -n
 1  bin: / PLUS
 2        |MINUS
 3        |TIMES
 4        |DIV
 5        |MOD
 6        |GT
 7        |GE
 8        |LE
 9        |EQ
10        |NE
11        |LT
12        |AND
13        |EXP
14        |OR
15       /($x, $y)
16    => {
17      $x = char2int($_[0], 0);
18      $y = char2int($_[0], 1);
19
20      if (($x->{t} == $INT) and ( $y->{t} == $INT)) {
21        $_[0]->{t} = $INT;
22        return 1;
23      }
24      type_error("Incompatible types with operator '".($_[0]->lexeme)."'", $_[0]->line);
25    }

Modificación de la Semántica de las Expresiones Regulares

Obsérve la expresión regular lineal en las líneas 1-15. La semántica de las expresiones regulares lineales es modificada ligéramente por Parse::Eyapp::Treeregexp. Note que no se ha especificado la opción x. El compilador de expresiones regulares árbol la insertará por defecto. Tampoco es necesario añadir anclas de frontera de palabra \b a los identificadores que aparecen en la expresión regular lineal: de nuevo el compilador de expresiones regulares árbol las insertará.

Introducción de Nodos de Conversión de Tipos

Las subrutinas de conversión char2int e int2char se proveen - junto con la subrutina para emitir mensajes de error - como código de apoyo a las expresiones árbol. Recuerde que en un programa Treeregexp puede incluir código Perl en cualquier lugar sin mas que aislarlo entre llaves. Dicho código será insertado - respetando el orden de aparición en el fuente - en el módulo generado por treereg:

pl@nereida:~/doc/casiano/PLBOOK/PLBOOK/code/Simple-Types/lib/Simple$ sed -ne '/^{$/,/^}$/p' Trans.trg | cat -n
 1  {
 2
 3    my $types; # reference to the hash containing the type table
 4    my ($INT, $CHAR, $VOID);
 5
 6    sub type_error {
 7      my $msg = shift;
 8      my $line = shift;
 9       die "Type Error at line $line: $msg\n"
10    }
11
12    sub set_types {
..      .......................
18    }
19
20    sub char2int {
21      my ($node, $i) = @_;
22
23      my $child = $node->child($i);
24      return $child unless $child->{t} == $CHAR;
25
26      my $coherced = Parse::Eyapp::Node->new('CHAR2INT', sub { $_[0]->{t} = $INT });
27      $coherced->children($child);  # Substituting $node(..., $child, ...)
28      $node->child($i, $coherced);  # by           $node(..., CHAR2INT($child), ...)
29
30      return $coherced;
31    }
32
33    sub int2char {
34      my ($node, $i) = @_;
35
36      my $child = $node->child($i);
37      return $child unless $child->{t} == $INT;
38
39      my $coherced = Parse::Eyapp::Node->new('INT2CHAR', sub { $_[0]->{t} = $CHAR });
40      $coherced->children($child); # Substituting $node(..., $child, ... )
41      $node->child($i, $coherced); # by           $node(..., INT2CHAR($child), ...)
42
43      return $coherced;
44    }
45
46  }
Si el hijo i-ésimo del nodo $node es de tipo $CHAR, la línea 26 creará un nuevo nodo. Mediante el manejador pasado como segundo argumento a Parse::Eyapp::Node->new se dota al nodo del atributo t, el cual se establece a $INT. El nuevo nodo se interpone entre padre e hijo (líneas 27 y 28). De este modo se facilita la labor de la fase posterior de generación de código, explicitando la necesidad de generar código de conversión.

Si el lenguaje tuviera mas tipos numéricos, FLOAT, DOUBLE etc. es útil hacer especifico en el tipo del nodo que operación binaria se esta realizando cambiando el tipo PLUS en PLUSDOUBLE, PLUSINT etc. según corresponda.

Expresiones Constantes

La asignación de tipo a los nodos que se corresponden con expresiones constantes es trivial:

nereida:~/doc/casiano/PLBOOK/PLBOOK/code/Simple-Types/lib/Simple> \
    sed -ne '60,61p' Trans.trg | cat -n
     1  inum: INUM($x) => { $_[0]->{t} = $INT }
     2  charconstant: CHARCONSTANT($x) => { $_[0]->{t} = $CHAR }

Ejemplo

Sigue un ejemplo de comprobación de tipos en expresiones:
pl@nereida:~/Lbook/code/Simple-Types/script$ usetypes.pl prueba18.c 2
1 int c[20][30], d;
2
3 int f(int a, int b) {
4   if (c[2] > 0)
5   return
6      (a+b)*d*c[1][1];
7 }
Type Error at line 4: Incompatible types with operator '>'



Subsecciones
Casiano Rodríguez León
2009-12-17