Regístrate | Conectar
El Tamiz Libros Recursos Series Únete 20 Users Online
Skip to content

Computador mágico XXVI – El compilador




La serie “El computador mágico” está disponible también en forma de libro.

En el último capítulo de esta serie presentamos el ordenador C16B y el concepto de subrutina, y escribimos un programa que calculaba el factorial de un número. Pero vimos que el programa empezaba a ser demasiado grande y que nos iba resultando útil describir su funcionamiento con algún tipo de pseudolenguaje, así que describíamos nuestro programa tal que así:

numero = 6
resultado = 1
mientras (numero != 0) {
  resultado = multiplicar(resultado,numero)
  numero = numero -1
}
# El resultado está en resultado
subrutina multiplicar(p, q) {
  res = 0
  mientras (p != 0) {
    p = p -1
    res = res + q
  }
  devolver res
}
 

Supongo que te resulta mucho más sencillo de entender, ¿verdad?

 

Haz ahora un ejercicio: en el capítulo anterior lo que hicimos fue escribir el programa en ensamblador y luego describirlo de esta forma un poco más abstracta. Pero… ¿serías capaz de hacer lo contrario? Es decir, si te doy el programa descrito en esta forma abstracta, ¿serías capaz de convertirlo en las instrucciones de ensamblador correspondientes?

Espero que la respuesta sea un sí, claro.

Pues eso es lo que hace un compilador: primero nos inventamos un lenguaje que sea más cercano al natural (no te sorprenderá que se base en el inglés) y luego el compilador traduce eso a código máquina. Por ejemplo, si quisiéramos escribir ese mismo programa en (algo parecido a) C,[1] haríamos lo siguiente:

int multiplicar(int p, int q) {
  int res = 0;
  while (p != 0) {
    p = p - 1;
    res = res + q;
  }
  return res;
}
int numero = 6;
int resultado = 1;
while (numero != 0) {
  resultado = multiplicar(resultado, numero);
  numero = numero -1;
}
// Al llegar aqui, resultado ya tiene el factorial
 

Supongo que, a poco inglés que sepas, eres capaz de deducir qué es lo que hace este código en C.

Pues bien, con esto hemos inventado los lenguajes de programación.

El programa, escrito en este lenguaje de programación, se llama “código fuente”. Lo que se carga en la memoria del ordenador para ser ejecutado se llama “código objeto” o “binario” u “objeto” u otras cosas así. El proceso de convertir el código fuente en el código objeto se llama “compilar”.

 

¿Podríamos hacer un programa que tome el código fuente y genere automáticamente el código binario? Sí, claro que podemos, no es más que una traducción de un formato a otro. No solo eso, sino que, además, dada la complejidad de los ordenadores actuales, el nivel de abstracción de los lenguajes de programación modernos y la potencia de los compiladores de hoy en día, el código binario que generan los compiladores es a menudo mejor que lo que podría lograr un ser humano típico escribiendo directamente el programa en ensamblador. No vamos a ver nada sobre teoría de compiladores, supongo que entre lo que hemos visto antes y estos párrafos eres capaz de entender que hacer esa traducción, esa compilación, es posible.

Lo que hemos visto es un lenguaje de programación, el lenguaje C, que es de muy bajo nivel: se dice que un lenguaje de programación es de más bajo nivel cuanto más cercano al código ensamblador está en su nivel de abstracción. C es un lenguaje de muy bajo nivel (hasta el punto de que a menudo se le llama, peyorativamente, “ensamblador de alto nivel”, para indicar que es “poco más que el ensamblador”).[2] Otros lenguajes también de bajo nivel son Pascal o Fortran.

Fíjate en que en estos lenguajes se definen estructuras de datos y funciones (lo que nosotros hemos llamado subrutinas) que se van llamando unas a otras astutatemente para operar con dichos datos… y poco más. Esto es lo que se llama programación procedural o programación imperativa.[3]

Pero a la gente rápidamente se le ocurrió que podía dar un nivel más de abstracción, inventando otros paradigmas de programación. Así, por ejemplo, se inventó la programación orientada a objetos. En ella se definen objetos, que tienen una serie de propiedades  y de operaciones. Puede parecer que es muy parecido a la programación imperativa, y es que de hecho está basada en ella. Su mayor potencia radica en que los objetos “heredan” cosas unos de otros. Así por ejemplo, podemos tener un objeto de tipo Vehículo, que tiene una propiedad que es la Velocidad y una operación que es Acelerar. Podemos también tener un objeto de tipo Coche, que es “hijo” del tipo Vehículo. Como es hijo de Vehículo, tiene todas sus propiedades y operaciones, pero puede también definir propiedades y operaciones nuevas. Por ejemplo, puede tener la propiedad NumeroDeRuedas y la operación CambiarRueda… pero ojo, que sigue teniendo la propiedad Velocidad y la operación Acelerar. O también podemos tener otro tipo, el tipo Barco, que también es hijo de Vehículo, con un par de propiedades nuevas Eslora y NumeroDeCubiertas, y con la operación Atracar. Como Barco es hijo de Vehículo, tiene la propiedad Velocidad y la operación Acelerar, pero como no tiene nada que ver con Coche no tiene ninguna operación llamada CambiarRueda.[4] En fin, es un ejemplo muy tonto, pero combinando adecuadamente esos objetos y operaciones se pueden hacer cosas muy complejas.

La programación orientada a objetos probablemente es hoy en día el paradigma más extendido, en lenguajes como C++, Java, Objetive C, C#, PHP…[5] Existen otros paradigmas, pero, y espero que sus partidarios no se me tiren al cuello, no están tan extendidos: programación funcional, programación lógica, programación declarativa… sus partidarios sostienen que SUSTITUYA-AQUÍ-SU-PARADIGMA-FAVORITO le dice al ordenador qué tiene que hacer, mientras que la programación imperativa (y su hija, la programación orientada a objetos) le dice al ordenador cómo tiene que hacerlo, y que por eso SUSTITUYA-AQUÍ-SU-PARADIGMA-FAVORITO es mejor. Ni que decir tiene que algo de razón lleva, pero limitar la discusión a “X es mejor que Y” es muy superficial.

No vamos a entrar más en detalle en teoría de lenguajes, pues llevaría para un libro entero. Este capítulo, que ha sido ligerito en comparación de a lo que estamos habituados, servirá para que veas que en el futuro veremos muchas cosas de una forma más abstracta, sin escribir tanto ensamblador. En el próximo capítulo veremos la última de las versiones de C16, el C16C.

 

  1. C es un lenguaje de programación, probablemente el más famoso de todos. []
  2. Ojo: “bajo nivel” no significa que sea malo. Hace referencia a su nivel de abstracción, no a si es bueno o malo. []
  3. Su definición formal es mucho más farragosa, algo así como “el paradigma que se basa en definir un estado y cambios sobre dicho estado”… que en el fondo no es más que lo que nosotros sabemos que es un circuito secuencial. []
  4. Bueno, es su “hermano”, pero en este paradigma eso no importa. []
  5. Estoy obviando que muchos de estos lenguajes son interpretados, o se ejecutan sobre máquinas virtuales… si no sabes de qué hablo, no te preocupes, no es necesario. []

Sobre el autor:

J ( )

 

Escribe un comentario

Tu dirección de correo no es mostrada. Los campos requeridos están marcados *

Al escribir un comentario aquí nos otorgas el permiso irrevocable de reproducir tus palabras y tu nombre/sitio web como atribución.