domingo, noviembre 27, 2005

Operador Ellipsis

Operador Ellipsis

#include <cstdlib>
#include <iostream>
#include <stdarg.h>
using namespace std;

int sumavar(int , ... );
int main(int argc, char *argv[]) {
     cout<<"La suma es: "<<sumavar(9,1,2,3,4,5,6,7,8,9)<<endl;
    system("PAUSE");
    return 0;
}
int sumavar(int size, ...) {
     va_list ap;    
     int *tmp = 0,r=0;
     va_start(ap, size);
     for (int i=0; i<size;i++){
           tmp = va_arg(ap, int *);
           r=r+(int)tmp;  
     }
    va_end(ap);    
    return r;
}

Nota: el primer parámetro que se manda es la cantidad de parámetros variables que serán sumados, ya que si no envía este parámetro empieza a obtener datos basuras del stack que maneja C/C++, este stack es manejado mediante la librería “stdarg.h”

Convenciones de llamada de las arquitecturas MIPS e Intel
Invocación C
Esta opción indica al compilador utilizar la secuencia de llamada estándar C para funciones, es decir: Generar guiones de subrayado -guiones bajos-; distinguir mayúsculas de minúsculas (no transformar minúsculas en mayúsculas); pasar parámetros de derecha a izquierda.
Las funciones que utilizan esta convención de llamada pueden aceptar una lista variable de parámetros (su número no tiene que ser fijo) y utilizan la pila para el paso de argumentos.  La función que realiza la llamada es la encargada de limpiar la pila, lo que provoca que el código de este tipo de ejecutables sean ligeramente mayores que en el resto de las convenciones, en las que es la función invocada la que limpia la pila.
Invocación Pascal
Esta opción indica al compilador utilizar la secuencia de llamada de Pascal para las funciones (no generar guiones de subrayado, forzar identificadores a mayúsculas, limpieza de la pila por la función que realiza la llamada y paso de parámetros de izquierda a derecha).
Generalmente las llamadas de función resultantes son más pequeñas y rápidas que las generadas con la convención C, y también utilizan la pila para el paso de parámetros.  En este caso las funciones deben pasar el número exacto de argumentos y del tipo adecuado.  Los identificadores de las funciones declaradas con este modificador están sujetos al planchado de nombres

domingo, noviembre 20, 2005

Mejoras en la Interfaz Grafica

Mejoras en la Interfaz gráfica

Todas la palabras claves del lenguaje pascal (procedure, var, function, etc) se distinguen de lo demás mediante color, así sucede también con los números, caracteres, cadenas de string.
También la interfaz cuenta con una opción de poder realizar búsqueda de palabras, si la encuentra será remarcada mediante un color.

Además, cuando sucede un error el carrete del cursor se ubica en la posición del error.







Chequeo de Tipos

Chequeo de Tipos

  1. Verifica que una expresión sea del mismo tipo de la variable a la que es asignada, {x:=4+5 --> integer:=integer}. Esta verificación es valida para todo tipo de combinación de expresiones (números, caracteres, String, variables)

  1. Verifica que cuando una función o un procedimiento es llamado y este tiene parámetros, se verifica la cantidad de parámetros, el cual debe corresponder a la cantidad de parámetros cuando la función o procedimiento fue declarado. Además, verifica si la función o procedimiento en su declaración no tiene parámetros y al ser llamados se le asignaron parámetros.

  1. Chequea el tipo de los parámetros, los parámetros que se asignaron al ser llamada la función o procedimiento debe ser igual al tipo de parámetros cuando la función o procedimiento fue definida.

  1. Verifica que un procedimiento no pueda ser asignado a una variable.

  1. Con respecto a los operadores, verifica que todos los elementos sean del mismo tipo. {5+x*6, todos son del tipo integer, en caso contrario es error }

  1. Se verifica que cuando se define un arreglo, el rango siempre debe ser del tipo integer {c[1] ó c[x], 1 y x son del tipo integer }

Nota: las cadenas de string no son aceptado como parámetros, solamente parámetros de tipo integer ó char.

domingo, noviembre 13, 2005

Atributos Heredados

Atributos Heredados en CUP

En CUP los atributos heredados solo pueden ser simulados, es decir declarando variables (Objetos, clases, etc.) en la parte de declaración de usuario de CUP, y utilizar estas variables (como atributos heredados simulados) para almacenar la información y poder ser utilizada de acuerdo a la definición de Atributo Heredado. Por lo investigado en Internet, esta fue la mejor manera; es posible que internamente CUP hago utilidad de atributos heredados, pero no estoy seguro.

domingo, noviembre 06, 2005

Ejercicios 6.3 y 6.5 (Libro Aho)

Ejercicios 6.3 y 6.5 (Libro Aho)

6.3)      P ( D ; E
     D ( D1 ; D2
     D ( id : T { añadetipo(id.entrada,T.tipo) }
     T ( char { T.tipo := char }
     T ( integer { T.tipo := integer }
     T ( list of T1 { T.tipo := agregarLista(T1.tipo) }
     E ( literal { E.tipo := char }
     E ( num { E.tipo := integer }
     E ( id { E.tipo := buscar(id.entrada) }
     E ( ( L ) { E.tipo := L.tipo }     
     L ( E , L1 { L.tipo := if E.tipo=integer and L1=integer then integer
                                  else if E.tipo=char and L1=char then char
                    else error_tipo()  }
     L ( E { L.tipo := E.tipo }

6.5)
  1. c: char; i:integer;
     c mod i mod 3

     P( D ; E
     D( D ; D
     D( id : T { añadetipo(id.entrada,T.tipo) }
     E ( E1 mod L { E.tipo := if E1.tipo=integer and L.tipo=integer then integer
                      else error_tipo() }
     E( literal { E.tipo := char }
     E ( num { E.tipo := integer }
     E ( id { E.tipo := buscar(id.entrada) }
     L( E1 mod E2 { L.tipo := if E1.tipo=integer and E2.tipo=integer then integer
                      else error_tipo()  }
     T ( char { T.tipo := char }
     T ( integer { T.tipo := integer }

  1. P: ↑integer; a:array[10] of integer;
     a[↑p]

     P( D ; E
     D( D ; D
     D( id : T { añadetipo(id.entrada,T.tipo) }
     E ( num { E.tipo := integer }
     E ( id { E.tipo := buscar(id.entrada) }
     E ( E1 [ E2 ] { E.tipo := if E2.tipo =integer and E1.tipo=array(s,t) then t
                                      else error_tipo() }
     E ( E1↑ { E.tipo := if E.tipo=pointer(t) then t
                               else error_tipo() }
     T ( integer { T.tipo := integer }
     T ( ↑T1 { T.tipo := pointer(T1.tipo) }
     T ( array [ num ] of T1{ T.tipo:= array(1..num.value, T1.tipo) }





  1. f:integer ( boolean;
     i;integer; j:integer; k:ineger;
     while f(i) do
          k := i;
          i := j mod i;
          j := k

P( G ; D ; E
     G( id : T ( T { añadetipo(id.entrada,T.tipo) }
     D( D ; D
     D( id : T { añadetipo(id.entrada,T.tipo) }
     E( while E1 ( E2 ) S { E.tipo := if E2=integer then true                         
                          else false }
     E ( num { E.tipo := integer }
     E ( boolean { E.tipo := boolean }
     E ( id { E.tipo := buscar(id.entrada) }
     E ( E1 mod E2 { E.tipo := if E1.tipo=integer and E2.tipo=integer then integer
                      else error_tipo() }
     S( S ; S
     S( id := E
     T ( char { T.tipo := char }
     T ( integer { T.tipo := integer }
     T ( boolean { T.tipo :=  boolean }