# XHarbour

xHarbour es un compilador extendido de Clipper en múltiples plataformas de ordenador (DOS, Microsoft Windows, Linux (32 y 64 bits), Unix (32 y 64 bits), Mac OS X), ofreciendo múltiples terminales gráficas y drivers de consola, GUIs (libres como HWGui, MiniGUI, ooHG, t-gtk y comerciales como Visual xHarbour, FiveWin, Xailer), e híbridos entre consola y GUIs (Graphic User Interface o Interfaz Gráfica de Usuario) como GTWvt y GTWvw. xHarbour es 100% compatible Clipper y soporta muchas sintaxis de extensiones del lenguaje, ampliamente extendidas librerías runtime como OLE, ODBC, MySQL, PostgreSQL, TIpt, TXml, RegEx, HbZip, xbScript y un amplio soporte de terceras partes.
xHarbour es un proyecto Open Source, se distribuye bajo licencia GPL y por tanto es gratuito. Se incluye una excepción a la GPL para poder soportar aplicaciones comerciales. El proyecto fue dado a la luz por Ron Pikas a finales del 2002.
Como la mayoría de los lenguajes dinámicos, xHarbour está también disponible como un lenguaje de script (uso independiente, biblioteca enlazable, motor de MS ActiveScript [Windows Script Host, HTML, ASP]) utilizando un intérprete escrito en el lenguaje xHarbour.

## Tipos de datos incorporados

xHarbour tiene 6 tipos escalares : Null, String, Fecha, FechaHora, Lógico, Numérico, Puntero, y 4 tipos complejos: Array, Objeto, CodeBlock, y Hash. Un escalar almacena un valor sencillo, como una cadena de caracteres, número, o referencia a cualquier otro tipo. Las matrices (Arrays) son listas ordenadas de escalares o tipos complejos, indexadas por un número, comenzando en 1. Los Hashs, o arrays asociativos, son colecciones ordenadas por su clave asociada, que puede ser de tipo String, Fecha o Numérico, y el valor contenido puede ser cualquier tipo escalar o complejo.
Representación (estática) literal de tipos escalares:
* Null: NIL
* String: "hola", 'hola', [hola], or E"hola\n"
* Fecha: ctod("2005-03-17" )
* FechaHora: ctot("2005-03-17 09:30:00.000")
* Lógico: .T., .F.
* Numérico: 1, 1.1, -1, 0xFF
Los tipos complejos pueden también representarse como valores literales:
* Array: { "String"", 1, { "Array anidado" }, .T., LlamadaFunction, @PunteroFunction }
* CodeBlock: { |Arg1, ArgN| Arg1 := ArgN + OuterVar + LlamadaFunction }
* Hash: { "Nombre" => "Juan", 1 => "Clave numérica", { "Anidado" => "Hash" } }
Los Hashs solo pueden utilizar tipos String, Fecha o Número como la clave para cualquier elemento. Hashs y Arrays pueden contener cualquier tipo como el Valor de cualquier miembro, incluyendo otros arrays anidados y Hashs.
Los Codeblocks pueden tener referencias a Variables de la Procedure/Function>method (Procedimiento/Función>método) en que fueron definidos. Esos Codeblocks pueden devolver un valor, o mediante un argumento pasado por referencia, en cuyo caso el Codeblock "sobrevive" a la rutina en que fue definido, y cualquier variable que referencie, será una variable SEPARADA.
Las variables separadas mantendrán su valor mientras que todavía exista un Codeblock que las referencie. Tales valores serán compartidos con cualquier otro Codeblock que pueda tener acceso a esas mismas variables. Si el Codeblock no sobrevive a la rutina que contenía, y es evaluado durante el periodo de vida de la rutinaen que es definida, los cambios a sus Variables Separadas por medio de su evaluación, se reflejarán de vuelta en la rutina padre.
Los Codeblocks pueden evaluarse cuantas veces se necesario, por medio de la función Eval( BlockExp ).

## Variables

Todos los tipos pueden asignarse a variables nombradas. Los identificadores de variables nombradas puden tener de 1 a 63 caracteres de largo, comienzan con [A-Z|_] y constar de los caracteres [A-Z|0-9|_] hasta un máximo de 63 caracteres. Las variables nombradas no son sensibles a mayúsculas/minúsculas (las variables JuAn y juan son la misma).
Las Variables pueden tener uno de los siguientes tipos de visibilidad:
* LOCAL: Visible solo en la rutina en que se han declarado. El valor se pierde al salir de la rutina.
* STATIC: (estática) Visible solo en la rutina en que se han declarado. El valor se preserva en invocaciones subsiguientes de la rutina. Si una variable STATIC se declara antes del Procedimiento/Función/Método en que se define, tene un alcance de MODULE (módulo), y es visible dentro de cualquier rutia definida en el mismo archivo fuente, manteniendo su vida durante la vida de la aplicación.
* GLOBAL: Visible en cualquier rutina definida en el mismo archivo fuente en que la variable GLOBAL es declarada, así como en cualquier rutina de cualquier otro archivo fuente que la declare explícitamente, por medio de la declaración GLOBAL EXTERNAL. Las declaraciones GLOBAL y EXTERNAL deben hacerse antes de que se defina cualquier Procedimiento/Función/Método.
* PRIVATE: Visible solo en la rutina en que se declara y en las rutinas llamadas por esa rutina.
* PUBLIC: Visible para todas las rutinas en la misma aplicación.
LOCAL, STATIC, y GLOBAL se resuelven en tiempo de compilación, y son mucho más rápidas que las variables PRIVATE y PUBLIC que son entidades dinámicas a las que se accede por medio de la Symbol table del runtime. Por la misma razón las variables LOCAL, STATIC y GLOBAL no son accesibles al compilador de Macros, y cualquier código macro que intente referenciarlas dará un error en tiempo de ejecución.
Debido a la naturaleza dinámica de las variables PRIVATE y PUBLIC, pueden ser creadas y destruidas en tiempo de ejecución, pueden leerse y modificarse por medio de macros runtime, y pueden leerse y modificarse por Codeblocks creados al vuelo.

## Operador Macro (compilación al vuelo)

Una de las más poderosas características de los lenguajes xBase es el operador de MACRO &. La implementación en xHarbour del Operador de Macro permite la compilación en tiempo de ejecución de cualquier expresión válida en xHarbour. Esa expresión compilada puede utilizarse como un VALOR, es decir, la parte derecha de una asignación, pero es más interesante la posibilidad de usar esa expresión compilada como la parte izquierda de una asignación, es decir, declarar variables PRIVATE o PUBLIC, CAMPOS de una base de datos.
Adicionalmente el Operador de Macro puede compilar y ejecutar llamadas a funciones, asignaciones completas, o incluso listas de argumentos, y el resultado de la macro se puede utilizar para resolver uno de los contextos de la aplicación compilada. Cualquier aplicación xHarbour puede ser extendida y/o modificada en tiempo de ejecución, para compilar y para ejecutar código adicional en demanda.
El operador macro puede compilar y ejecutar además llamadas de función, asignaciones completas, o aún la lista de discusiones, y el resultado de la macro se puede utilizar para resolver un de los sobre contextos en el uso compilado. IOW, cualquier uso del xHarbour puede ser extendido, y/o modificado en tiempo de pasada, para compilar y para ejecutar código adicional en demanda.
La implementación en xHarbour de esta característica es tan completa que el intérprete de script de xHarbour, xbScript, utiliza intensamente esa característica para compilar los scripts xHarbour.
Sintaxis:
El valor del texto de la expresión '...' será compilado, y el resultado de ejecutar ese código compilado será devuelto.
es la abreviatura de &( SomeId ).
es la abreviatura de &( SomeId + "postfix" ).

## Script

xHarbour está también disponible como un lenguaje interpretado en varias implementaciones de motores de script.
* Stand alone Interpreter: Portable, autocontenido, intérprete xBaseScript.
* ActiveScript: OLE DLL compatible Microsoft ActiveScript que soporta el script xHarbour en:
** Windows Script Host (WSH).
** Internet Explorer, script HTML del lado del cliente.
** IIS, y otros servidores web compatibles ASP.