\layout Standard
De los tipos básicos pueden derivarse otros tipos.
- Esto tipos son punteros, array y funciones, siendo estas últimas tal vez
- un caso muy particular.
+ Esto tipos son punteros, array (estáticos, dinámicos y asociativos) y funciones
+, siendo estas últimas tal vez un caso muy particular.
Los array tal vez podrían considerarse tipos compuestos, pero como la variable
en sí es un puntero, en realidad no lo es.
Es decir, para obtener un elemento del array hay que aplicar aritmética
implícitamente
\emph default
utilizando el operador corchetes.
+\layout LyX-Code
+
+char[] str =
+\begin_inset Quotes eld
+\end_inset
+
+hola
+\begin_inset Quotes erd
+\end_inset
+
+; // Array dinámico de caracteres
+\layout LyX-Code
+
+str =
+\begin_inset Quotes eld
+\end_inset
+
+hola todos
+\begin_inset Quotes erd
+\end_inset
+
+; // Se autoredimensiona
+\layout LyX-Code
+
+int[2] arr; // Array (estático) de 2 int
+\layout LyX-Code
+
+int[char[]] hash; // Array asociativo de int cuya clave es un char[]
+\layout LyX-Code
+
+void function() fp; // Puntero a una función void (void)
+\layout LyX-Code
+
+int function(bit) fp2; // Puntero a una función int (bit)
+\layout LyX-Code
+
+int delegate(bit) del; // Delegado de tipo int (bit)
+\layout Standard
+
+Los delegados son algo así como punteros a función con contexto.
+ El contexto puede ser tanto un objeto como un
+\emph on
+frame pointer
+\emph default
+ (el puntero al stack en donde se encuentra el padre lexicográfico de una
+ función anidada).
+ Veremos un poco más los delegados en la sección
+\begin_inset LatexCommand \vref{sub:Operaciones}
+
+\end_inset
+
+ y en la
+\begin_inset LatexCommand \vref{sub:Rutinas}
+
+\end_inset
+
+.
\layout Subsection
Tipos de usuario
Expresiones
\layout Subsection
+
+\begin_inset LatexCommand \label{sub:Operaciones}
+
+\end_inset
+
Operaciones
\layout Standard
-D provee operaciones las operaciones básicas que provee prácticamente cualquier
- lenguaje: asignación, comparación, incremento, decremento, suma, resta,
- multiplicación, división, resto, algebra booleana (and, or, xor, not),
- shifting.
- También provee llamadas a funciones.
- Los procedimientos son un caso particular de funciones que no devuelven
- nada (void).
+D provee las operaciones básicas que provee prácticamente cualquier lenguaje:
+ asignación, comparación, incremento, decremento, suma, resta, multiplicación,
+ división, resto, algebra booleana (and, or, xor, not), shifting.
+\layout LyX-Code
+
+int i = 1 << 1; // 0001b << 1 == 0010b == 2
+\layout LyX-Code
+
+int j = i >> 1; // 2 >> 1 == 0010b >> 1 == 0001b == 1
+\layout LyX-Code
+
+i -= j; // i = i - j = 2 - 1 = 1
+\layout LyX-Code
+
+i = -i; // i = -1
+\layout LyX-Code
+
+i *= 4; // i = i * 4 = -1 * 4 = -4
+\layout LyX-Code
+
+i >>>= 1; // i = i >>> 1 = 1100b >>> 1 = 1110b = -2
+\layout LyX-Code
+
+i++; // i = i + 1 = -2 + 1 = -1
+\layout LyX-Code
+
+i |= j; // i = i | j = 1111b | 0001b = 1111b = -1
+\layout LyX-Code
+
+i &= j; // i = i & j = 1111b & 0001b = 0001b = 1
+\layout LyX-Code
+
+bit c = i > j; // c = 1 > 1 = false
+\layout LyX-Code
+
+c = i && j; // c = 1 && 1 = true
+\layout LyX-Code
+
+i = 3 / 2; // i = 3 / 2 = 1 (entero)
+\layout LyX-Code
+
+i = 3 % 2; // i = resto(3/2) = 1
+\layout Standard
+
+También provee llamadas a funciones y delegados.
+\layout LyX-Code
+
+printf(
+\begin_inset Quotes eld
+\end_inset
+
+Hola mundo
+\backslash
+n
+\begin_inset Quotes erd
+\end_inset
+
+); // Llama a void printf(char*, ...)
+\layout LyX-Code
+
+bit ok = esta_ok(10, 1.5); // Llama a bit esta_ok(int, float)
+\layout LyX-Code
+
+int n = objeto.cantidad(); // Llama a int Clase::cantidad(Clase)
+\layout LyX-Code
+
+int delegate(void) delegado;
+\layout LyX-Code
+
+delegado = &objeto.cantidad;
+\layout LyX-Code
+
+n = delegado(); // Llama a objeto.cantidad()
\layout Standard
Además de esto, provee operaciones propias de un lenguaje imperativo de
bajo nivel: aritmética de punteros, operador [] como método alternativo
para acceder a una posición de un array, desreferenciamiento, obtención
de una dirección de memoria de una variable, etc.
- También incluye un operador para comparar si 2 referencias referencian
- al mismo objeto y algunas operaciones propias de los arrays, como para
- saber si un elemento está dentro del array o concatenación de arrays y
- slicing.
+\layout LyX-Code
+
+int[2] arr;
+\layout LyX-Code
+
+arr[1] = 1; // asigno el segundo elemento (empieza en 0)
+\layout LyX-Code
+
+int* p = cast(int*) arr + 1; // apunto a arr[1]
+\layout LyX-Code
+
+*p = 2; // arr[1] = 2
+\layout LyX-Code
+
+*(--p) = 1; // p apunta a arr[0] y arr[0] = 1
+\layout LyX-Code
+
+p = &(arr[1]); // p apunta a arr[1]
+\layout Standard
+
+También incluye un operador para comparar si 2 referencias referencian al
+ mismo objeto.
+\layout LyX-Code
+
+class C { int i = 0; int opEquals(C o) { return i == o.i; } }
+\layout LyX-Code
+
+C c1 = new C;
+\layout LyX-Code
+
+C c2 = new C;
+\layout LyX-Code
+
+C c3 = c1;
+\layout LyX-Code
+
+c1.i = c2.i = 1;
+\layout LyX-Code
+
+c1 is c2; // false
+\layout LyX-Code
+
+c1 is c3; // true
+\layout LyX-Code
+
+c1 == c2; // true
+\layout Standard
+
+y algunas operaciones propias de los arrays y hashes (array asociatios),
+ como para saber si existe una clave o concatenación y slicing de arrays.
+\layout LyX-Code
+
+int[3] arr;
+\layout LyX-Code
+
+arr[1] = 10;
+\layout LyX-Code
+
+int[2] arr2;
+\layout LyX-Code
+
+arr2[1] = 1;
+\layout LyX-Code
+
+arr3 = arr ~ arr2; // arr3 = (0,10,0,0,1)
+\layout LyX-Code
+
+int[float] hash;
+\layout LyX-Code
+
+hash[1.1] = 1;
+\layout LyX-Code
+
+1.0 in hash; // false
+\layout LyX-Code
+
+1.1 in hash; // true
\layout Standard
Finalmente provee un operador de resolución de scope, para acceder a variables
\layout Subsection
Variables
-\layout Comment
-
-Si hay o no variables sin nombre
\layout Standard
-El lenguaje cuenta con tipado débil, con conversiones implícitas, por ejemplo,
- entre punteros.
+El lenguaje provee variables sin nombre a través de punteros y alocación
+ manual de memoria.
+ En general las instancias de clases son referencias (no puede ser alocadas
+ en el stack, en principio), por lo que podría decirse que toda instancia
+ de clase es una variable sin nombre.
+ Para alocar memoria se puede usar el operador
+\family typewriter
+new
+\family default
+ que aloca memoria
+\emph on
+vigilada
+\emph default
+ por el recolector de basura, o a través de la llamada al malloc de C (en
+ el módulo
+\family typewriter
+std.c.stdlib
+\family default
+ en D), que aloca memoria no
+\emph on
+vigilada
+\emph default
+ por el recolector.
+ El manejo de referencias es automático, no hay forma de declarar una variable
+ de tipo referencia.
+ Si la variable es de tipo clase, será una referencia, si no no (con algunas
+ excepciones, como al pasarse por parámetro).
+ Si se desean usar variables sin nombre que no sean clases, hay que usar
+ punteros.
+\layout LyX-Code
+
+import std.c.stdlib;
+\layout LyX-Code
+
+int* p = cast(int*) malloc(4 * int.sizeof); // Nunca serán recolectados
+\layout LyX-Code
+
+p[3] = 1;
+\layout LyX-Code
+
+free(p); // Lo libero yo
\layout Subsection
Representación de la memoria
a mano
\emph default
e inicializar el objeto en esa memoria, pero no es el caso general).
+\layout Standard
+
+Como dijimos, los tipos simples ocupan una cantidad de memoria fija cada
+ uno.
+ Cada tipo derivado tiene sus propias particularidades.
+\layout Subsubsection
+
+array estático
+\layout Standard
+
+El array estático no es más que una región contigua de bytes de tamaño N*S,
+ siendo N la cantidad de elementos y S el tamaño que ocupa el elemento.
+ Una variable de este tipo, entonces, no es más que un puntero al primer
+ elemento.
+\layout Subsubsection
+
+array dinámico
+\layout Standard
+
+Los array dinámicos, como su nombre lo indica, no tienen un tamaño fijo,
+ por lo tanto se guarda el tamaño además de los elementos en sí.
+ Una variable de este tipo es entonces un indicador de la cantidad actual
+ de elementos y un puntero al primer elemento.
+ Es por esto que típicamente este tipo de array ocupa 8 bytes (4 bytes para
+ almacenar N y 4 bytes para almacenar el puntero al primer elemento, que
+ se establecen en tiempo de ejecución) más los N*S para los elementos en
+ sí.
+\layout Subsubsection
+
+array asociativo (o hash)
+\layout Standard
+
+La representación de este tipo de array no está aún definida, aunque al
+ igual que los array dinámico dice que la referencia ocupa 8 bytes, pero
+ no indica para que sirve cada byte, aunque es esperable que sea igual,
+ 4 bytes para la cantidad de memoria alocada para la tabla de hash y 4 para
+ el puntero a la tabla en sí.
+\layout Subsubsection
+
+enum
+\layout Standard
+
+No es más que un int con un rango de valores posibles predefinidos y con
+ nombres simbólicos, por lo que simplemente se almacena como un int y todos
+ los chequeos se realizan en tiempo de compilación.
+\layout Subsubsection
+
+union
+\layout Standard
+
+Las uniones ocupan en memoria, como mínimo, la misma la cantidad de bytes
+ que ocupa su elemento de mayor tamaño.
+ Como el tipo que se está usando para acceder se sabe en tiempo de compilación,
+ no es necesario almacenar datos extra, pero podría ocupar más lugar si
+ el compilador hiciera alguna optimización (para que ocupe múltiplos de
+ una palabra, por ejemplo).
+\layout Subsubsection
+
+struct
+\layout Standard
+
+Las estructuras, al igual que en C, se almacenan de forma contínua ocupando,
+ como mínimo,
+\begin_inset Formula $\sum S_{i}$
+\end_inset
+
+ siendo
+\begin_inset Formula $S_{i}$
+\end_inset
+
+ el tamaño del elemento i del struct.
+ Nuevamente, los tamaños se conocen en tiempo de compilación por lo que
+ no es necesario guardar datos extra y ocupando más eventualmente si el
+ compilador optimiza.
+\layout Subsubsection
+
+class
+\layout Standard
+
+Las clases son seguramente las estructuras más complejas.
+ Basadas en las estructuras, le agregan datos de control para implementar
+ herencia y polimorfismo.
+ Para esto debe almacenarse, además de los elementos (no estáticos, o sea
+ de instancia) como en el struct, un puntero a una tabla virtual (vtable)
+ y un monitor, ocupando 4 bytes cada uno.
+ El monitor no está bien especificado para qué sirve, pero supongo que debe
+ estar relacionado al recolector de basura.
+ La tabla virtual, a su vez, está compuesta por un puntero a la instancia
+ de una clase ClassInfo (que guarda datos de la clase en sí) y por todos
+ los punteros a métodos virtuales (para implementar polimorfismo).
+ Los atributos estáticos (de clase), como ya se mencionó, se almacenan como
+ variables globales, ya que se conocen en tiempo de compilación.
+\layout Subsubsection
+
+function
+\layout Standard
+
+Los punteros a funciones se almacenan como un puntero común y corriente,
+ ya que la
+\emph on
+firma
+\emph default
+ de la función se conoce en tiempo de compilación y se sabe la cantidad
+ de datos que se deben apilar y desapilar al hacer el llamado, por lo que
+ todo ese código puede hacerse en tiempo de compilación independientemente
+ de donde se encuentre el código de la función a ejecutar.
+\layout Subsubsection
+
+delegate
+\layout Standard
+
+Los delegados deben tener la información del contexto, es por esto que ocupan
+ 8 bytes (en x86), 4 para el puntero al código de la función y 4 para el
+ puntero al contexto (sea una instancia de clase o un
+\emph on
+frame pointer
+\emph default
+).
+ Esto se comprobó empíricamente ya que no está definido aún.
\layout Subsection
Modelo de ejecución
\layout Standard
-D es un lenguaje imperativo compilado, por lo que d
+D es un lenguaje imperativo compilado, por lo que se basa en el modelo de
+ Von-Newman y sus 3 operaciones básicas:
+\layout Enumerate
+
+Fetch
+\layout Enumerate
+
+Incrementar IP
+\layout Enumerate
+
+Executar instrucción
+\layout Standard
+
+El llamado a funciones se hace a través de la pila, ya que soporta recursión
+ y hay una pila por cada hilo, ya que soporta multiples hilos.
+ Además de la cadena dinámica (para el llamado recursivo) tiene cadena estática,
+ ya que soporta funciones anidadas, con el modelo estático, que busca las
+ variables en el
+\emph on
+padre estructural
+\emph default
+ de la función y no en la función apilada inmediatamente arriba.
+\layout Comment
+
+Mencionar operaciones básicas: asignación, jump, push, pop, call, return
\layout Subsection
Punteros
Instrucciones
\layout Subsection
+
+\begin_inset LatexCommand \label{sub:Rutinas}
+
+\end_inset
+
Rutinas
+\layout Standard
+
+Los procedimientos son un caso particular de funciones que no devuelven
+ nada (void)
\layout Subsubsection
Pasaje de parámetros