Comprobación de Tipos: Indexados

Guía de Ruta en la Comprobación de Tipos para los Accesos a Arrays

En la comprobación de tipos de una expresión x[y1][y2] que referencia a un elemento de un array hay que tener en cuenta:

  1. Que el tipo declarado para la variable x debe ser array (líneas 4-9 del código que sigue)
  2. Que el número de dimensiones utilizadas en la expresión debe ser menor o igual que el declarado para la variable (líneas 11-17).
  3. Si x es un array de tipo t el tipo de x[2] será t. Por ejemplo, en la llamada g(x[y1][y2]) la variable x deberá haber sido declarada con al menos dos dimensiones. Si x fué declarada int x[10][20][30] el tipo de la expresión x[y1][y2] será A_30(INT).

  4. Que los índices usados deben ser de tipo entero. Si fueran de tipo CHAR podrán ser ahormados.

Código de Comprobación de Tipos para los Accesos a Arrays

Sigue el código para la comprobación de tipos de expresiones de referencias a elementos de un array:

nereida:~/doc/casiano/PLBOOK/PLBOOK/code/Simple-Types/lib/Simple> \
    sed -ne '97,125p' Trans.trg | cat -n
 1  arrays: VARARRAY($x, INDEXSPEC(@y))
 2     => {
 3
 4      my $t = $VARARRAY->{t}; # Type declared for VARARRAY
 5        type_error(           # Must be an array type
 6          " Variable '$x->{attr}[0]' was not declared as array",
 7          $VARARRAY->line
 8        )
 9      unless is_array($t);
10
11      my ($declared_dim, $used_dim, $ret_type) = compute_dimensionality($t, @y);
12
13        type_error(
14          " Variable '$x->{attr}[0]' declared with less than $used_dim dimensions",
15          $VARARRAY->line
16        )
17      unless $declared_dim >= $used_dim;
18
19      for (0..$#y) { # check that each index is integer. Coherce it if is $CHAR
20        my $ch = char2int($INDEXSPEC, $_);
21
22          type_error("Indices must be integers",$VARARRAY->line)
23        unless ($ch->{t} == $INT);
24      }
25
26      $VARARRAY->{t} = $ret_type;
27
28      return 1;
29    }

Funciones de Ayuda

La función compute_dimensionality llamada en la línea 11 se incluye dentro de la sección de funciones de soporte en Trans.trg:

 96  { # support for arrays
 97
 98    sub compute_dimensionality {
 99      my $t = shift;
100      my $i = 0;
101      my $q;
102      my $used_dim = scalar(@_);
103      for ($q=$t; is_array($q) and ($i < $used_dim); $q=$q->child(0)) {
104        $i++
105      }
106
107      croak "Error checking array type\n" unless defined($q);
108      return ($i, $used_dim, $q);
109    }
110
111    sub is_array {
112      my $type = shift;
113
114      defined($type) && $type =~ /^A_\d+/;
115    }
116
117    sub array_compatible {
118      my ($a1, $a2) = @_;
119
120      return 1 if $a1 == $a2;
121      # int a[10][20] and int b[5][20] are considered compatibles
122      return (is_array($a1) && is_array($a2) && ($a1->child(0) == $a2->child(0)));
123    }
124  }

Ejemplos

El siguiente ejemplo muestra la comprobacion de tipos de arrays en funcionamiento:

pl@nereida:~/Lbook/code/Simple-Types/script$ usetypes.pl prueba02.c 2
 1 int a,b,e[10];
 2
 3 g() {}
 4
 5 int f(char c) {
 6 char d;
 7  c = 'X';
 8  e[d][b] = 'A'+c;
 9  {
10    int d;
11    d = a + b;
12  }
13  c = d * 2;
14  return c;
15 }
16
Type Error at line 8:  Variable 'e' declared with less than 2 dimensions
El siguiente ejemplo muestra la comprobacion de tipos de que los índices de arrays deben ser enteros:
pl@nereida:~/Lbook/code/Simple-Types/script$ usetypes.pl prueba06.c 2
 1 int a,b,e[10][20];
 2
 3 g() {}
 4
 5 int f(char c) {
 6 char d[20];
 7  c = 'X';
 8  g(e[d], 'A'+c);
 9  {
10    int d;
11    d = a + b;
12  }
13  c = d * 2;
14  return c;
15 }
16
Type Error at line 8: Indices must be integers



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