Ir al contenido principal

Lenguaje C totalmente en castellano. Uso del preprocesador.

Sobre el castellano

¿Quisieras escribir código funcional en lenguaje C/C++ totalmente en castellano? Esto que sigue a continuación es algo que venía estudiando hace un par de años, jugando, probando, experimentando. Me ha permitido aprender de mi lenguaje materno (el castellano rioplatense xP) y contrastarlo con el lenguaje C, principalmente. Pero lo he discontinuado por comenzar a programar en JavaScript.
Miremos un poco el código siguiente:

#include <stdio.h>
#include "cafeCastellano.c"

Programa ( Mi sistema )
  
   Sea como Frase( suNombre ) ;
   Sea como Numero( suEdad, un Entero ) ;
  
   Consultar( "Decime tu nombre", suNombre, FRASE ) ;
   Consultar( "Decime tu edad", suEdad, ENTERO ) ;
  
   Decir(
      "Tu nombre es %s y tu edad es %d" ENTER
      , suNombre
      , suEdad
   ) ;
  
   Si suEdad > 30 Entonces
      Decir( "Ten"Ee"s m"Aa"s de 30" )
      /* Tenés más de 30 */
   caso Contrario
      Decir( "Esper"Aa" %d a"Nn"os m"Aa"s y tendr"Aa"s 30", (30-suEdad) )
      /* Esperá X años más y tendrás 30 */
   Fin(si)
  
   Terminar con 0 ;
Fin( del programa )
   

Está basado en el uso del preprocesador de C/C++, mediante la directiva #define. Este lenguaje es el único que he visto que lo procesa de esta manera. La cuestión es tratar de entender qué hace el #define y qué no es en realidad.

La directiva de preprocesador #define

Al principio, cuando nos enseñan programación, se nos indica que los #define nos sirven para declarar Constantes, aunque esto no es así, de ninguna manera. Es muy probable que ni los profesores sepan qué hace realmente un #define.
Para aclarar un #define lo que provoca es un código de reemplazo al pre-procesar código C. Esto es, por ejemplo, antes de compilar en binario final el código que creamos con el lenguaje, se preprocesa. Se convierte en el verdadero lenguaje C, oculto a la vista de los programadores.
Por ejemplo, la cláusula #include<> lo que hace es, antes de procesar en binario, abre un archivo, el indicado entre las llaves angulares o las comillas, copia todo su contenido, y lo pega en tu archivo real, aquél que será compilado. Es fácil de verlo si se analiza la función include() o require() de PHP.
Volviendo a #define, Define crea una palabra clave, cosa de no gastar memoria innecesaria cuando funcione nuestro programa ejecutándose, pero también que el codificador humano escriba menos.
Por ejemplo:
#define p printf
Se puede utilizar para...
p ( "Bienvenido %d \n" , SUsuario ) ;

Reemplazos vacíos

Una cosa buena de #define es que podemos utilizar reemplazos vacíos. Cosa de engañar al Editor de C/C++. Muchas de las cosas que tenemos en el Castellano es el uso de palabras que decoran el objeto y sujeto verdadero de los que hablamos. Digo, el Castellano es un lenguaje de alto nivel, mientras que C/C++ sería uno de medio nivel.
Por ejemplo...
#define Sea
#define como
#define numero int
Se definieron como nada, como elementos vacíos. El preprocesador reemplazará donde escribamos Sea y un por nada, y por ende desaparecerán una vez preprocesados. Así el código...
Sea como numero laEdad = 23 ;
Es exactamente lo mismo que...
int laEdad = 23 ;

Una habilidad que tienen los reemplazos del preprocesador es la de invocar a otro reemplazo. Entonces podemos definir palabras clave para decir lo mismo...
#define Sino else
#define Contrario Sino

Entonces será lo mismo redactar Sino que Contrario.

Reemplazos iterativos

O, podemos utilizarlo, si sabemos que podemos olvidarnos de cómo se escribía una palabra, pensando en que una palabra en mayúscula no es lo mismo que en minúscula en C/C++, cuidar esto de nuestro idioma el Castellano.
#define Sea
#define SEA Sea
#define sea Sea

Así será lo mismo escribir Sea que SEA o que sea.

Algo muy útil, pero muy útil para aprender nuestro idioma, y combinarlo con el C, es el tema del if-then-else, o, en castellano, si esto ocurre, entonces esto sucede, y si no, sucederá esto otro.
En el lenguaje C/C++ el if se utiliza de la siguiente manera:

if( variable > 34 ) {
  printf( "Es mayor que 34" ) ;
} else {
  printf( "Es menor o igual que 34" ) ;
}

Mediante el preprocesador podemos utilizar...
#define Si if(
#define Entonces ) {
#define Sino } else {
#define Fin }

Para convertir lo de arriba en lo pre-procesable siguiente...
Si variable > 34 Entonces
  printf( "Es mayor que 34" ) ;
Sino
  printf( "Es menor o igual que 34" ) ;
Fin

Muchas veces sucede que nos olvidamos de cerrar el punto y coma antes del } al cerrar un bloque del then-else o del else-endif. Y como Pascal, al colocar la palabra END no hace falta poner el último punto y coma (por esto comprendí que el lenguaje Pascal utiliza esto para compilar). Podemos redefinir el Fin como ; }
#define Fin ; }

Y a su vez el Sino
 #define Sino ; } else {

Por lo tanto, también podremos reescribir lo de arriba sin los punto y coma antes del Sino y del Fin.
Si variable > 34 Entonces
  printf( "Es mayor que 34" )
Sino
  printf( "Es menor o igual que 34" )
Fin

Pero esto no implica que las instrucciones anteriores a la inmediatamente anterior a Sino o a Fin no usen sus punto y coma.

El reemplazo no es solamente para palabras, sino que incluye símbolos

Ahora, notemos que ese Fin se puede utilizar en cualquier lado en que utilicemos el símbolo }. Un programa principal podría quedar como...

int main() {
// Codigo codigo codigo
Fin

Bueno, sería más legible que si utilizamos castellano en una parte, utilicemos en casi todo.

#define Programa int main() {
Entonces...
Programa ()
  // Codigo codigo codigo codigo
Fin

Macros. Reemplazos que manejan parámetros.

El último truquito que tienen los #define, bueno, que quiero destacar, es la posibilidad de utilizar paréntesis para indicar parámetros. A estas directivas o instrucciones de preprocesador que utilizan parámetros se las llama MACROS del preprocesador de C/C++.

A menudo se nos enseñan la siguiente macro para utilizar el #define. (Y por esto se confunden mucho con que es para crear CONSTANTES). El ejemplo de Triada de MacArthy (en C y derivados el operador ternario ?:, en Basic el IIF, en Excel la función =SI() )
#define valorSi( a, b, c ) (a) ? (b) : (c)

Para hacer lo siguiente, por ejemplo:
miVariable = valorSi( e > 34 , "Verdadero", "Falso" ) ;

Al principio podremos pensar que se trata de una función, ¡pero no es así! Es un reemplazo del preprocesador. Es decir, no ocupa memoria al ejecutarse nuestro programa binario, sino que el preprocesador convierte ese renglón en lo siguiente:

miVariable = (e > 34) ? "Verdadero" : "Falso" ;

Pero es más fácil leerlo en castellano.

Volviendo a las macros, se pueden crear macros con parámetros, pero no es necesario utilizar estos últimos al aplicarlos. Me explico. La magia de esto es que podemos crear código auto-explicado :o
Por ejemplo, puedo asignarle a qué va dirigido un fin (por ejemplo, "Fin programa", "Fin for", "Fin Sí", "Fin mientras", etc.)
O indicar que el programa es de otra cosa. Veamos la definición de estas macros y comparemos qué es lo que se procesa al final.

#define Programa( cosas ) int main() {
#define Fin( deQue ) }

Entonces puede salir esta maravilla, totalmente funcional...

Programa( Mi super ultra programa en castellano 3443443 )
  Sea como Numero cantObreros = 23 ;
  Si cantObreros < 15 Entonces
    printf( "Pocos obreros" )
  Sino
    printf( "Muchos obreros" )
  Fin( del Si )
Fin( del programa, eso es todo amigos )


Código útil

Volviendo al código de arriba, lo siguiente es el código fuente no avanzado para lograr el castellano, el archivo cafeCastellano.c

/* [Café Castellano] */

/* Existencia */
#define Sea
#define Sean Sea

/* Tipos */
#define Frase(cual) char cual[255]
   #define Entero       int
   #define Real      float
   #define Decimales    float
#define Numero(variable, tipo) tipo variable

/* Palabras del lenguaje Castellano sin sentido en C */
#define que
#define la
#define el
#define los
#define las
#define un
#define unos
#define algun
#define algunos
#define algunas
#define con
#define de
#define en
#define caso
#define como
#define y
#define o

/* Cuestiones del lenguaje C */
#define Decir printf

#define Programa( abcd )   int main( char** Argumentos ) {
#define Fin(deQue)         ; }
#define Mientras        while(
#define Repetir            ) {
#define Terminar        return
#define Devolver        Terminar
#define Si              if(
#define Entonces        ) {
#define Sino            ; } else {
#define Contrario          Sino
#define Verificar(a)       switch(a){
#define Posibilidad( a )   case a :
#define Cancelar        break

/* Consultar al usuario */
#define ConsultarFRASE( mensaje, variable ) \
   printf( mensaje": " ) ; \
   gets( variable )
#define ConsultarENTERO( mensaje, variable ) \
   printf( mensaje": " ) ; \
   scanf( "%d", &variable )
#define ConsultarDECIMAL( mensaje, variable ) \
   printf( mensaje": " ) ; \
   scanf( "%f", &variable )

#define FRASE 
#define ENTERO   
#define DECIMAL  

#define Consultar( Mensaje, Variable, Tipo ) \
   Consultar##Tipo ( Mensaje, Variable ) ;

#define yy &&
#define oo ||

/* Caracteres escapables en las STRINGS */
#define ENTER "\n"
#define Aa "\xA0"
#define AA "\xA0"
#define Ee "\x82"
#define EE "\x82"
#define Ii "\xA1"
#define Ii "\xA1"
#define Oo "\xA2"
#define Oo "\xA2"
#define Uu "\xA3"
#define Uu "\xA3"
#define Nn "\xA4"
#define NN "\xA5"


 Postdata

* Se pueden definir varios códigos separados por renglones para una misma macro o reemplazo, utilizando el símbolo \.
* Esto lo estudié hace unos años, hará por allá en 2012. Estuve desarrollando una especie de librería útil para redactar todo en castellano pero en un accidente informático perdí todo el desarrollo. Sin embargo fue tal el aprendizaje que en cualquier momento puedo desarrollarlo nuevamente y cada vez mejor.

Comentarios

Entradas populares de este blog

Probando ChatGPT - Mapa conceptual con Mermaid

 Había conversado con ChatGPT acerca de cuidado de las plantas e hidroponía. Luego de unos días me di cuenta que quizás también podría saber acerca de crear Mapas conceptuales. Salió lo siguiente; le falta un concepto para crear correctamente mapas conceptuales (la relación entre los conceptos), pero podría ser algo para ayudarnos a corregir mejor. El texto original era el que cito a continuación, pero le agregué explícitamente que me armara un "mapa conceptual" utilizando el lenguaje Mermaid, un lenguaje descriptivo que permite construir gráficos diversos, entre ellos Mapas conceptuales, generando un archivo SVG. ``` Hacé un mapa conceptual en lenguaje Mermaid con el siguiente texto, redactado anteriormente: "La hidroponía es un método de cultivo que se utiliza para cultivar plantas sin suelo utilizando una solución nutriente y agua. Algunas plantas pueden cultivarse con éxito mediante hidroponía, mientras que otras necesitan el suelo para crecer y prosperar. De las pl...

Conectar a Servidor Node.JS desde VB6 o VBA

El presente código sirve tanto para Visual Basic 6.0 (sí, todavía sirve, todavía sirve!) como para Visual Basic para Aplicaciones (Excel o VBA). ' Si estamos en Visual Basic para Aplicaciones agregar la referencia ' WinHTTP, en el menú Herramientas, Referencias, Microsoft WinHTTP Services Function Solicitar( _ ByVal URLBase As String _ , Optional ByVal Puerto As Integer = 80 _ , Optional ByVal Seccion As String = "" _ , Optional ByVal Metodo As String = "GET" _ ) As String On Error GoTo solucion #If VBA6 Then Dim objXML As New WinHttpRequest #ElseIf Win32 Then Dim objXML As Object Set objXML = CreateObject("MSXML2.ServerXMLHTTP") #End If objXML.Open Metodo, URLBase & ":" & Puerto & "/" & Seccion, False objXML.send If (objXML.Status = 404) Then Solicitar = "404 Error" Else Solicitar = objXML.responseText End If Se...