1138 lines
38 KiB
Markdown
1138 lines
38 KiB
Markdown
### Prefacio Arquitectónico
|
||
|
||
**AVAP es un DSL (Domain-Specific Language) Turing Completo, diseñado arquitectónicamente para la orquestación segura, concurrente y determinista de microservicios e I/O.** No es un lenguaje de propósito general; su motor híbrido y su gramática estricta están optimizados para el procesamiento rápido de transacciones HTTP, la manipulación de datos en memoria y la persistencia, minimizando los efectos secundarios no deseados.
|
||
|
||
---
|
||
|
||
# Especificación Técnica Consolidada del Lenguaje AVAP (LRM)
|
||
|
||
Este documento unifica la arquitectura de memoria, estructuras de control, modularidad, concurrencia asíncrona y la gramática formal (BNF) del lenguaje AVAP. Actúa como la única fuente de verdad (Single Source of Truth) para la implementación del parser, el motor de ejecución y la indexación del sistema RAG.
|
||
|
||
---
|
||
|
||
## SECCIÓN I: Arquitectura, Memoria y Fundamentos Estructurales
|
||
|
||
Esta sección sienta las bases de cómo AVAP gestiona la lógica de los servicios y la manipulación de datos en memoria. A diferencia de los lenguajes interpretados convencionales, AVAP utiliza un motor de evaluación híbrida que permite combinar comandos declarativos con expresiones dinámicas.
|
||
|
||
### 1.1 Estructura de Archivo y Terminación de Sentencias
|
||
AVAP es un lenguaje **estrictamente orientado a líneas**. Esta decisión de diseño garantiza que el analizador sintáctico (parser) sea extremadamente rápido y determinista, evitando la ambigüedad que sufren lenguajes que permiten declaraciones en múltiples líneas.
|
||
* Cada instrucción lógica (`statement`) debe completarse en una única línea física de texto.
|
||
* El motor reconoce el salto de línea o retorno de carro (`<EOL>`) como el terminador absoluto de la instrucción.
|
||
* No se admite la partición de una instrucción, obligando al programador a escribir un código secuencial, limpio y fácil de depurar.
|
||
|
||
### 1.2 Registro de Endpoints (registerEndpoint)
|
||
El comando `registerEndpoint` es la unidad atómica de configuración en AVAP. Actúa como el puente crítico entre la red externa (HTTP) y el código interno.
|
||
* **Mecánica:** Define la ruta URL, el método HTTP permitido (ej. `GET`, `POST`), y la función de entrada principal (Handler).
|
||
* **Seguridad:** El servidor AVAP rechazará automáticamente (con un Error 405) cualquier petición que no coincida con el método especificado.
|
||
* **Middlewares:** Permite inyectar una lista de funciones previas para validar tokens antes de ejecutar el bloque principal.
|
||
|
||
### 1.3 Asignación Dinámica y Referencias (addVar)
|
||
AVAP permite una sintaxis de asignación directa mediante el símbolo `=`, otorgando flexibilidad bajo un estricto control de contexto.
|
||
* **Evaluación en tiempo real:** Cuando el intérprete lee `variable = expresión`, resuelve cualquier operación matemática o lógica utilizando el motor de evaluación subyacente.
|
||
* **El operador de desreferenciación (`$`):** Cuando se utiliza el comando nativo `addVar(copia, $original)`, el prefijo `$` indica al motor que debe buscar en la tabla de símbolos la variable llamada "original" y extraer su valor.
|
||
* **Semántica de addVar:** El comando acepta `addVar(valor, variable)` o `addVar(variable, valor)`. Si ambos argumentos son identificadores, el valor del segundo se asigna al primero. No está permitido usar dos literales como argumentos.
|
||
|
||
### Especificación BNF (Sección I)
|
||
|
||
```bnf
|
||
<program> ::= ( <line> | <block_comment> )*
|
||
<line> ::= [ <statement> ] [ <line_comment> | <doc_comment> ] <EOL>
|
||
| ( <line_comment> | <doc_comment> ) <EOL>
|
||
<EOL> ::= /* Retorno de carro / Salto de línea (\n o \r\n) */
|
||
|
||
<statement> ::= <assignment>
|
||
| <method_call_stmt>
|
||
| <function_call_stmt>
|
||
| <function_decl>
|
||
| <return_stmt>
|
||
| <system_command>
|
||
| <io_command>
|
||
| <control_flow>
|
||
| <async_command>
|
||
| <connector_cmd>
|
||
| <db_command>
|
||
| <http_command>
|
||
| <util_command>
|
||
| <modularity_cmd>
|
||
|
||
<assignment> ::= <identifier> "=" <expression>
|
||
|
||
/* Llamada a función global (sin receptor de objeto) */
|
||
<function_call_stmt> ::= <identifier> "(" [<argument_list>] ")"
|
||
|
||
/* Llamada a método sobre un objeto conector (con receptor) */
|
||
<method_call_stmt> ::= <identifier> "=" <identifier> "." <identifier> "(" [<argument_list>] ")"
|
||
|
||
<system_command> ::= <register_cmd> | <addvar_cmd>
|
||
<register_cmd> ::= "registerEndpoint(" <stringliteral> "," <stringliteral> "," <list_display> "," <stringliteral> "," <identifier> "," <identifier> ")"
|
||
/* addVar asigna un valor a una variable. Acepta (valor, variable) o (variable, valor).
|
||
Si ambos argumentos son identificadores, el valor del segundo se asigna al primero.
|
||
No está permitido pasar dos literales como argumentos. */
|
||
<addvar_cmd> ::= "addVar(" <addvar_arg> "," <addvar_arg> ")"
|
||
<addvar_arg> ::= <identifier> | <literal> | "$" <identifier>
|
||
/* Restricción semántica: al menos uno de los dos <addvar_arg> debe ser <identifier> */
|
||
|
||
<identifier> ::= [a-zA-Z_] [a-zA-Z0-9_]*
|
||
|
||
/* Variables de sistema reservadas — accesibles y asignables desde cualquier scope:
|
||
_status — código HTTP de respuesta (ej. addVar(_status, 401) o _status = 404) */
|
||
<system_variable> ::= "_status"
|
||
```
|
||
|
||
---
|
||
|
||
## SECCIÓN II: Gestión de Entrada y Salida (I/O)
|
||
|
||
Esta sección describe los mecanismos que AVAP utiliza para la ingesta de datos externos, la validación de la integridad de los parámetros y la construcción del paquete de respuesta HTTP. AVAP no posee comandos de impresión interna (como `print`); toda salida de datos se realiza a través de la interfaz HTTP.
|
||
|
||
### 2.1 Captura Inteligente de Parámetros (addParam)
|
||
El comando `addParam(parametro, destino)` inspecciona la petición HTTP en un orden jerárquico estricto: primero en la URL (Query arguments), luego en el JSON Body, y finalmente en el Form Data. Si el parámetro solicitado no existe, la variable de destino se inicializa como `None`.
|
||
|
||
### 2.2 Validación y Colecciones (getListLen / getQueryParamList)
|
||
* **`getListLen(fuente, destino)`**: Actúa como un inspector de volumen. Cuenta cuántos elementos hay en una lista o cadena.
|
||
* **`getQueryParamList(parametro, lista_destino)`**: Empaqueta automáticamente múltiples ocurrencias de un parámetro de URL (ej. `?filtro=A&filtro=B`) en una única estructura de lista.
|
||
|
||
### 2.3 Construcción de Respuesta (addResult y _status)
|
||
El comando `addResult(variable)` es el encargado de registrar qué variables formarán parte del cuerpo JSON de la respuesta final. La variable de sistema `_status` permite definir explícitamente el código HTTP de salida tanto mediante asignación directa (`_status = 404`) como mediante `addVar(_status, 401)`.
|
||
|
||
### Especificación BNF (Sección II)
|
||
|
||
```bnf
|
||
<io_command> ::= <addparam_cmd> | <getlistlen_cmd> | <addresult_cmd> | <getparamlist_cmd>
|
||
<addparam_cmd> ::= "addParam(" <stringliteral> "," <identifier> ")"
|
||
<getlistlen_cmd> ::= "getListLen(" <identifier> "," <identifier> ")"
|
||
<getparamlist_cmd> ::= "getQueryParamList(" <stringliteral> "," <identifier> ")"
|
||
<addresult_cmd> ::= "addResult(" <identifier> ")"
|
||
```
|
||
|
||
---
|
||
|
||
## SECCIÓN III: Lógica de Control y Estructuras de Decisión
|
||
|
||
AVAP utiliza una gramática estructural mixta. Combina la fluidez de las palabras clave para abrir bloques funcionales con la seguridad matemática de cierres estrictos.
|
||
|
||
### 3.1 El Bloque Condicional (if() / else() / end())
|
||
La estructura `if()` evalúa una expresión lógica o de comparación. Todo bloque condicional requiere un cierre explícito utilizando el comando `end()`.
|
||
|
||
El comando `if()` soporta dos modos de invocación:
|
||
* **Modo 1 (comparación estructurada):** `if(variable, valor, comparador)` — evalúa la comparación entre variable y valor usando el operador indicado como string (ej. `"=="`, `">"`, `"!="`). Los dos primeros argumentos deben ser identificadores simples o literales, nunca expresiones de acceso como `dict['clave']`. Si se necesita comparar un valor extraído de una estructura, debe asignarse primero a una variable.* **Modo 2 (expresión libre):** `if(None, None, expresion_compleja)` — evalúa directamente una expresión booleana compleja proporcionada como string encapsulado entre `.
|
||
|
||
## SECCIÓN III: Lógica de Control y Estructuras de Decisión
|
||
|
||
AVAP utiliza una gramática estructural mixta. Combina la fluidez de las palabras clave para abrir bloques funcionales con la seguridad matemática de cierres estrictos.
|
||
|
||
### 3.1 El Bloque Condicional (if() / else() / end())
|
||
El comando `if()` gestiona la lógica condicional mediante dos modos de invocación estrictamente diferenciados. Es imperativo respetar los delimitadores y la posición de los argumentos.
|
||
|
||
#### Modo 1: Comparación Estructurada (Atómica)
|
||
Se utiliza para comparaciones directas entre dos valores simples.
|
||
* **Sintaxis:** `if(átomo_1, átomo_2, "operador")`
|
||
* **Argumentos 1 y 2:** Deben ser identificadores simples (variables) o literales (strings/números). **No se permite el uso de `None` en este modo.**
|
||
* **Argumento 3:** El operador de comparación debe ir obligatoriamente entre **comillas dobles** (`"=="`, `"!="`, `">"`, `"<"`, `">="`, `"<="`).
|
||
* **Restricción:** No se permiten expresiones de acceso (ej. `data.user` o `list[0]`). Estos valores deben asignarse previamente a una variable.
|
||
* **Ejemplo correcto:** `if(reintentos, 5, "<")`
|
||
|
||
#### Modo 2: Expresión Libre (Evaluación Compleja)
|
||
Se utiliza para evaluar expresiones lógicas que no encajan en la estructura atómica.
|
||
* **Sintaxis:** `if(None, None, `expresión_compleja`)`
|
||
* **Argumentos 1 y 2:** Deben ser literalmente la palabra `None` (sin comillas).
|
||
* **Argumento 3:** La expresión completa **debe** estar encapsulada entre **acentos graves (backticks)**. Esto permite incluir lógica interna, operadores `and/or` y accesos a estructuras de datos.
|
||
* **Ejemplo correcto:** `if(None, None, `user.id > 10 and email.contains("@")`)`
|
||
|
||
---
|
||
|
||
### Tabla de Validación para el Modelo
|
||
|
||
| Entrada | Estado | Razón |
|
||
| :--- | :--- | :--- |
|
||
| `if(count, 10, "==")` | ✅ VÁLIDO | Modo 1: Átomos válidos y operador entre comillas. |
|
||
| `if(None, None, `val > 0`)` | ✅ VÁLIDO | Modo 2: Uso correcto de `None` y backticks. |
|
||
| `if(username, None, "==")` | ❌ ERROR | El Modo 1 prohíbe el uso de `None`. Debe usarse el Modo 2. |
|
||
| `if(None, None, "val > 0")` | ❌ ERROR | El Modo 2 requiere backticks (`` ` ``), no comillas. |
|
||
| `if(user.id, 10, "==")` | ❌ ERROR | El Modo 1 no permite expresiones de acceso (`.`). |
|
||
|
||
### 3.2 Iteraciones Estrictas y Deterministas (startLoop / endLoop)
|
||
Para garantizar el determinismo y evitar el colapso de memoria:
|
||
* Los bucles se definen mediante `startLoop(contador, inicio, fin)`. Solo iteran basándose en índices numéricos finitos.
|
||
* El bloque debe cerrarse obligatoriamente con `endLoop()`.
|
||
* La forma de salir anticipadamente es invocando el comando global `return()`.
|
||
|
||
### 3.3 Gestión de Errores en Tiempo de Ejecución (try() / exception() / end())
|
||
Diseñada para proteger la estabilidad del servidor ante fallos de I/O.
|
||
* Si ocurre un fallo del sistema dentro del bloque `try`, el flujo salta al bloque `exception(variable_error)`, poblando la variable con la traza para facilitar la recuperación del script.
|
||
|
||
### Especificación BNF (Sección III)
|
||
|
||
```bnf
|
||
<control_flow> ::= <if_stmt> | <loop_stmt> | <try_stmt>
|
||
|
||
<if_stmt> ::= "if(" <if_condition> ")" <EOL>
|
||
<block>
|
||
[ "else()" <EOL> <block> ]
|
||
"end()" <EOL>
|
||
|
||
<if_condition> ::= <if_structured> | <if_free_expression>
|
||
|
||
<if_structured> ::= "if" "(" <strict_atom> "," <strict_atom> "," <backtick_string> ")"
|
||
<if_free_expression> ::= "if" "(" "None" "," "None" "," <backtick_string> ")"
|
||
|
||
<strict_atom> ::= <identifier> | <non_null_literal>
|
||
<backtick_string> ::= "`" <text_content> "`"
|
||
|
||
<identifier> ::= [a-zA-Z_][a-zA-Z0-9_]*
|
||
<non_null_literal>::= <number> | <string_literal_double_quotes>
|
||
/* Nota: <non_null_literal> NO incluye la palabra "None" */
|
||
|
||
<loop_stmt> ::= "startLoop(" <identifier> "," <expression> "," <expression> ")" <EOL>
|
||
<block>
|
||
"endLoop()" <EOL>
|
||
|
||
<try_stmt> ::= "try()" <EOL>
|
||
<block>
|
||
"exception(" <identifier> ")" <EOL>
|
||
<block>
|
||
"end()" <EOL>
|
||
|
||
<block> ::= <line>*
|
||
```
|
||
|
||
---
|
||
|
||
## SECCIÓN IV: Concurrencia y Asincronía
|
||
|
||
Implementa un sistema avanzado basado en hilos ligeros (gorutinas), permitiendo que el servidor procese operaciones de E/S largas sin bloquear el hilo principal.
|
||
|
||
### 4.1 Comando Lanzador (go)
|
||
* **Sintaxis:** `identificador = go nombre_funcion(parametros)`.
|
||
* **Mecánica:** Crea un nuevo contexto de ejecución aislado. Devuelve un identificador único que debe guardarse para interactuar con el hilo posteriormente.
|
||
|
||
### 4.2 Comando Sincronizador (gather)
|
||
* **Sintaxis:** `resultado = gather(identificador, timeout)`.
|
||
* **Mecánica:** Pausa el hilo principal esperando el resultado. Si se supera el `timeout` especificado, cancela la espera y devuelve `None`.
|
||
|
||
### Especificación BNF (Sección IV)
|
||
|
||
```bnf
|
||
<async_command> ::= <go_stmt> | <gather_stmt>
|
||
<go_stmt> ::= <identifier> "=" "go" <identifier> "(" [<argument_list>] ")"
|
||
<gather_stmt> ::= <identifier> "=" "gather(" <identifier> ["," <expression>] ")"
|
||
```
|
||
|
||
---
|
||
|
||
## SECCIÓN V: Conectores de Terceros, Peticiones HTTP y ORM Nativo
|
||
|
||
Agrupa todas las capacidades de interconexión hacia el exterior, permitiendo consumir integraciones de terceros, APIs externas y administrar bases de datos relacionales sin drivers adicionales.
|
||
|
||
### 5.1 Conectores de Terceros (avapConnector)
|
||
|
||
`avapConnector` es el mecanismo de integración con servicios de terceros configurados en la plataforma AVAP. Un conector se registra previamente mediante un UUID único. Al instanciarlo, la variable se convierte en un **objeto proxy** que encapsula credenciales y contexto, exponiendo métodos dinámicos mediante notación de punto.
|
||
|
||
**Patrón de uso:**
|
||
```avap
|
||
// 1. Instanciar el conector usando su UUID
|
||
belvo_connector = avapConnector("20908e93260147acb2636967021fbf5d")
|
||
|
||
// 2. Invocar métodos dinámicos (resueltos en runtime)
|
||
institutions = belvo_connector.list_institutions()
|
||
balances = belvo_connector.get_balances(link, account_id)
|
||
|
||
// 3. Resultado tratable como variable estándar
|
||
addResult(balances)
|
||
```
|
||
|
||
### 5.2 Cliente HTTP Externo (RequestPost / RequestGet)
|
||
|
||
Para evitar hilos bloqueados por latencia de red, AVAP exige un parámetro de **timeout** (en milisegundos). Si se supera, la variable destino recibe `None`.
|
||
|
||
* **`RequestPost(url, querystring, headers, body, destino, timeout)`**: Ejecuta un POST almacenando la respuesta en `destino`.
|
||
* **`RequestGet(url, querystring, headers, destino, timeout)`**: Ejecuta un GET omitiendo el cuerpo.
|
||
|
||
### 5.3 Conector de Bases de Datos y ORM
|
||
|
||
AVAP utiliza `avapConnector("TOKEN")` para la hidratación segura de credenciales. Las operaciones se ejecutan sobre una tabla específica definida por el parámetro `tableName`.
|
||
|
||
* **`ormCheckTable(tableName, varTarget)`**: Verifica la existencia de una tabla en la base de datos conectada.
|
||
* **`ormCreateTable(fields, fieldsType, tableName, varTarget)`**: Comando DDL para creación de tablas.
|
||
* **`ormAccessSelect(fields, tableName, selector, varTarget)`**: Recupera registros. `fields` acepta `*` o lista de campos. El `selector` es la cláusula WHERE (puede estar vacío). Devuelve una lista de diccionarios.
|
||
* **`ormAccessInsert(fieldsValues, tableName, varTarget)`**: Inserción parametrizada de registros en la tabla `tableName`.
|
||
* **`ormAccessUpdate(fields, fieldsValues, tableName, selector, varTarget)`**: Modifica registros existentes. El `selector` es obligatorio para delimitar el alcance del cambio en la tabla `tableName`.
|
||
* **`ormDirect(sentencia, destino)`**: Ejecución de SQL crudo para consultas analíticas complejas.
|
||
|
||
|
||
|
||
---
|
||
|
||
### Especificación BNF (Sección V)
|
||
|
||
```bnf
|
||
/* Instanciación de conector de terceros y llamada a sus métodos dinámicos */
|
||
<connector_cmd> ::= <connector_instantiation> | <connector_method_call>
|
||
<connector_instantiation> ::= <identifier> "=" "avapConnector(" <stringliteral> ")"
|
||
<connector_method_call> ::= [ <identifier> "=" ] <identifier> "." <identifier> "(" [<argument_list>] ")"
|
||
|
||
/* Cliente HTTP con Timeout Obligatorio */
|
||
<http_command> ::= <req_post_cmd> | <req_get_cmd>
|
||
<req_post_cmd> ::= "RequestPost(" <expression> "," <expression> "," <expression> "," <expression> "," <identifier> "," <expression> ")"
|
||
<req_get_cmd> ::= "RequestGet(" <expression> "," <expression> "," <expression> "," <identifier> "," <expression> ")"
|
||
|
||
/* ORM y Persistencia (Estandarizado con tableName) */
|
||
<db_command> ::= <orm_direct> | <orm_check> | <orm_create> | <orm_select> | <orm_insert> | <orm_update>
|
||
<orm_direct> ::= "ormDirect(" <expression> "," <identifier> ")"
|
||
<orm_check> ::= "ormCheckTable(" <expression> "," <identifier> ")"
|
||
<orm_create> ::= "ormCreateTable(" <expression> "," <expression> "," <expression> "," <identifier> ")"
|
||
|
||
/* ormAccessSelect(fields, tableName, selector, varTarget) */
|
||
<orm_select> ::= "ormAccessSelect(" <orm_fields> "," <expression> "," [<expression>] "," <identifier> ")"
|
||
<orm_fields> ::= "*" | <expression>
|
||
|
||
/* ormAccessInsert(fieldsValues, tableName, varTarget) */
|
||
<orm_insert> ::= "ormAccessInsert(" <expression> "," <expression> "," <identifier> ")"
|
||
|
||
/* ormAccessUpdate(fields, fieldsValues, tableName, selector, varTarget) */
|
||
<orm_update> ::= "ormAccessUpdate(" <expression> "," <expression> "," <expression> "," <expression> "," <identifier> ")"
|
||
```
|
||
|
||
> **Nota de implementación:** `<connector_instantiation>` se distingue de `<orm_connector_init>` (ORM) únicamente por contexto semántico: el UUID pasado como argumento determina si el adaptador resuelto es un ORM de base de datos o un proxy de terceros. La gramática los trata de forma idéntica; el motor de ejecución selecciona el adaptador apropiado en runtime.
|
||
|
||
---
|
||
|
||
# SECCIÓN VI: Utilidades, Criptografía y Manipulación de Datos
|
||
|
||
AVAP incluye un set de comandos integrados de alto nivel para manipular tipos complejos (JSON y Listas), tiempos, textos y generar hashes.
|
||
|
||
---
|
||
|
||
## 6.1 Manipulación Nativa de Listas y Objetos JSON
|
||
|
||
Para extraer y mutar estructuras complejas, AVAP provee comandos nativos específicos. En AVAP, las listas **no se instancian con literales de array**, sino que se construyen y recorren a través de un conjunto cerrado de comandos especializados:
|
||
|
||
* **`variableToList(elemento, destino)`**: Fuerza a que una variable escalar se convierta en una estructura iterable de lista de un único elemento. Es el punto de entrada canónico para construir una lista desde cero a partir de un valor existente.
|
||
|
||
* **`itemFromList(lista_origen, indice, destino)`**: Extrae de forma segura el elemento contenido en la posición `indice` (base 0) de una lista. Equivale a un acceso por índice controlado.
|
||
|
||
* **`getListLen(lista, destino)`**: Calcula el número total de elementos contenidos en `lista` y almacena el resultado entero en `destino`. Imprescindible para construir bucles de recorrido seguro y para validar listas antes de acceder a sus índices. Se recomienda llamar siempre a `getListLen` antes de `itemFromList` para evitar accesos fuera de rango.
|
||
|
||
* **`variableFromJSON(json_origen, clave, destino)`**: Parsea un objeto JSON en memoria y extrae el valor correspondiente a la `clave`, almacenándolo en `destino`. El acceso es directo por nombre de propiedad.
|
||
|
||
* **`AddVariableToJSON(clave, valor, json_destino)`**: Inyecta dinámicamente una nueva propiedad dentro de un objeto JSON existente. Si la clave ya existe, su valor es sobreescrito.
|
||
|
||
**Patrón de recorrido típico en AVAP:**
|
||
|
||
```avap
|
||
// 1. Obtener longitud de la lista
|
||
getListLen(myList, len)
|
||
|
||
// 2. Iterar con índice controlado
|
||
i = 0
|
||
while (i < len) {
|
||
itemFromList(myList, i, currentItem)
|
||
// ... procesar currentItem ...
|
||
i = i + 1
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 6.2 Criptografía y Expresiones Regulares
|
||
|
||
* **`encodeSHA256(origen, destino)`** y **`encodeMD5(origen, destino)`**: Funciones criptográficas que encriptan de forma irreversible un texto. Vitales para el almacenamiento seguro de contraseñas y la verificación de integridad de datos. SHA-256 produce un digest de 64 caracteres hexadecimales y ofrece mayor resistencia criptográfica que MD5 (32 caracteres); se recomienda SHA-256 para nuevos desarrollos.
|
||
|
||
* **`getRegex(origen, patron, destino)`**: Aplica una Expresión Regular (`patron`) sobre la variable de origen, extrayendo la primera coincidencia exacta encontrada. El patrón sigue la sintaxis estándar compatible con Python `re`.
|
||
|
||
---
|
||
|
||
## 6.3 Transformación de Tiempo y Cadenas
|
||
|
||
### Fechas y Timestamps
|
||
|
||
AVAP provee tres comandos complementarios para cubrir todas las conversiones posibles entre representaciones de tiempo. Los tres soportan formatos de calendario en notación `strftime` de Python y cálculos con `TimeDelta` expresados en segundos (positivo para sumar, negativo para restar):
|
||
|
||
| Comando | Entrada | Salida |
|
||
|---|---|---|
|
||
| `getTimeStamp(fecha_string, formato, timedelta, destino)` | String de fecha | Epoch (entero) |
|
||
| `stampToDatetime(epoch, formato, timedelta, destino)` | Epoch (entero) | String de fecha |
|
||
| `getDateTime(formato, timedelta, zona_horaria, destino)` | — (ahora mismo) | String de fecha |
|
||
|
||
* **`getTimeStamp(fecha_string, formato, timedelta, destino)`**: Convierte un string de fecha legible a su valor Epoch (entero Unix). Útil para almacenar fechas y realizar cálculos aritméticos sobre ellas.
|
||
|
||
* **`stampToDatetime(epoch, formato, timedelta, destino)`**: Convierte un valor Epoch a un string de fecha con el formato especificado. Útil para presentar timestamps almacenados de forma legible.
|
||
|
||
* **`getDateTime(formato, timedelta, zona_horaria, destino)`**: Captura la fecha y hora actuales del sistema, aplica el ajuste `timedelta` y las convierte a la `zona_horaria` indicada antes de almacenar el resultado. Acepta cualquier zona horaria reconocida por la librería `pytz` de Python.
|
||
|
||
### Cadenas de Texto
|
||
|
||
* **`randomString(patron, longitud, destino)`**: Genera una cadena aleatoria de `longitud` caracteres cuyos símbolos están restringidos al conjunto definido por `patron` (expresión regular de caracteres). Útil para generar tokens de sesión, contraseñas temporales o identificadores únicos.
|
||
|
||
* **`replace(origen, patron_busqueda, reemplazo, destino)`**: Localiza todas las ocurrencias de `patron_busqueda` dentro de `origen` y las sustituye por `reemplazo`, almacenando el resultado en `destino`. Facilita el saneamiento y normalización de datos de entrada antes de su procesamiento o almacenamiento.
|
||
|
||
---
|
||
|
||
## BNF — Gramática Formal de los Comandos de Utilidad
|
||
|
||
```bnf
|
||
<util_command> ::= <json_list_cmd> | <crypto_cmd> | <regex_cmd>
|
||
| <datetime_cmd> | <stamp_cmd> | <string_cmd> | <replace_cmd>
|
||
|
||
/* Manipulación de listas y JSON */
|
||
<json_list_cmd> ::= "variableToList(" <expression> "," <identifier> ")"
|
||
| "itemFromList(" <identifier> "," <expression> "," <identifier> ")"
|
||
| "getListLen(" <identifier> "," <identifier> ")"
|
||
| "variableFromJSON(" <identifier> "," <expression> "," <identifier> ")"
|
||
| "AddVariableToJSON(" <expression> "," <expression> "," <identifier> ")"
|
||
|
||
/* Criptografía */
|
||
<crypto_cmd> ::= "encodeSHA256(" <expression> "," <identifier> ")"
|
||
| "encodeMD5(" <expression> "," <identifier> ")"
|
||
|
||
/* Expresiones regulares */
|
||
<regex_cmd> ::= "getRegex(" <identifier> "," <expression> "," <identifier> ")"
|
||
|
||
/* Fecha/hora actual → string */
|
||
<datetime_cmd> ::= "getDateTime(" <stringliteral> "," <expression> "," <stringliteral> "," <identifier> ")"
|
||
/* Argumentos: formato_salida, timedelta, zona_horaria, destino */
|
||
|
||
/* Conversiones epoch ↔ string */
|
||
<stamp_cmd> ::= "stampToDatetime(" <expression> "," <stringliteral> "," <expression> "," <identifier> ")"
|
||
/* Argumentos: epoch_origen, formato, timedelta, destino */
|
||
| "getTimeStamp(" <stringliteral> "," <stringliteral> "," <expression> "," <identifier> ")"
|
||
/* Argumentos: fecha_string, formato_entrada, timedelta, destino */
|
||
|
||
/* Cadenas */
|
||
<string_cmd> ::= "randomString(" <expression> "," <expression> "," <identifier> ")"
|
||
/* Argumentos: patron, longitud, destino */
|
||
|
||
<replace_cmd> ::= "replace(" <identifier> "," <stringliteral> "," <stringliteral> "," <identifier> ")"
|
||
/* Argumentos: origen, patron_busqueda, reemplazo, destino */
|
||
```
|
||
|
||
|
||
---
|
||
|
||
## SECCIÓN VII: Arquitectura de Funciones y Ámbitos (Scopes)
|
||
|
||
Las funciones son recintos herméticos de memoria. Al entrar en una función, AVAP crea un nuevo diccionario de variables locales aislado del contexto global.
|
||
El comando `return()` actúa como interruptor de flujo: inyecta el valor calculado al llamador, libera la memoria local, y si se usa dentro de un `startLoop`, rompe la iteración anticipadamente.
|
||
|
||
### Especificación BNF (Sección VII)
|
||
|
||
```bnf
|
||
/* Nota: las funciones utilizan llaves {} como delimitadores de bloque por decisión
|
||
arquitectónica explícita, diferenciándose de las estructuras de control (if, loop, try)
|
||
que usan palabras clave de cierre (end(), endLoop()). Ambos patrones coexisten
|
||
en la gramática y el parser los distingue por el token de apertura. */
|
||
<function_decl> ::= "function" <identifier> "(" [<param_list>] ")" "{" <EOL>
|
||
<block>
|
||
"}" <EOL>
|
||
<param_list> ::= <identifier> ("," <identifier>)*
|
||
<return_stmt> ::= "return(" [<expression>] ")"
|
||
```
|
||
|
||
---
|
||
|
||
## SECCIÓN VIII: Modularidad e Inclusiones
|
||
|
||
* **Inclusión Estática (`include`)**: Directiva de preprocesador que pega el contenido de un fichero físico en la línea actual.
|
||
* **Librerías (`import`)**: Carga colecciones de funciones. Corchetes angulares (`import <math>`) para nativas, comillas (`import "mis_utils"`) para locales.
|
||
|
||
### Especificación BNF (Sección VIII)
|
||
|
||
```bnf
|
||
<modularity_cmd> ::= <include_stmt> | <import_stmt>
|
||
<include_stmt> ::= "include" " " <stringliteral>
|
||
<import_stmt> ::= "import" " " ( "<" <identifier> ">" | <stringliteral> )
|
||
```
|
||
|
||
---
|
||
|
||
## SECCIÓN IX: Expresiones y Gramática Léxica Estricta
|
||
|
||
Esta sección es el corazón matemático evaluador de AVAP. Define la jerarquía exacta (Precedencia) y provee soporte nativo para características avanzadas similares a Python.
|
||
|
||
### 9.1 Cast de Tipos Explícito
|
||
AVAP permite conversiones de tipos (Type Casting) en cualquier evaluación utilizando funciones constructoras estándar. Puedes transformar variables dinámicamente usando `int(var)`, `float(var)` o `str(var)`.
|
||
|
||
### 9.2 Slicing y Comprensiones (Comprehensions)
|
||
* **Slicing (Cortes):** Puedes extraer fragmentos de listas o strings utilizando la notación de dos puntos. Ejemplo: `mi_lista[1:4]` (extrae desde el índice 1 hasta el 3).
|
||
* **Comprehensions:** AVAP soporta la construcción rápida de listas mediante iteradores en una sola línea, permitiendo filtrar y mapear colecciones enteras (ej. `[x * 2 for x in valores if x > 0]`).
|
||
|
||
### 9.3 Análisis Léxico (Lexer) y Documentación
|
||
AVAP cuenta con tres niveles de descarte de texto para anotaciones humanas:
|
||
1. **Comentarios de Línea (`//`):** Ignora el texto hasta el salto de línea.
|
||
2. **Comentarios de Bloque (`/* ... */`):** Para aislar bloques enteros multilínea.
|
||
3. **Comentarios de Documentación (`///`):** Utilizados por analizadores de código o IDEs para generar documentación técnica automática (Docstrings) a partir del código fuente.
|
||
|
||
### Especificación BNF (Sección IX)
|
||
|
||
```bnf
|
||
/* Jerarquía de Expresiones (Precedencia de menor a mayor) */
|
||
<expression> ::= <logical_or>
|
||
<logical_or> ::= <logical_and> ( "or" <logical_and> )*
|
||
<logical_and> ::= <logical_not> ( "and" <logical_not> )*
|
||
<logical_not> ::= "not" <logical_not> | <comparison>
|
||
|
||
<comparison> ::= <arithmetic> ( <comp_op> <arithmetic> )*
|
||
<comp_op> ::= "==" | "!=" | "<" | ">" | "<=" | ">=" | "in" | "is"
|
||
|
||
<arithmetic> ::= <term> ( ( "+" | "-" ) <term> )*
|
||
<term> ::= <factor> ( ( "*" | "/" | "%" ) <factor> )*
|
||
<factor> ::= ( "+" | "-" ) <factor> | <power>
|
||
<power> ::= <primary> [ "**" <factor> ]
|
||
|
||
/* Primarios y Átomos (Accesos, Castings, Slicing, Métodos y Funciones)
|
||
La regla <primary> cubre también el acceso a métodos de objetos conector
|
||
(conector.metodo(...)) y el acceso por clave a sus resultados (resultado["key"]) */
|
||
<primary> ::= <atom>
|
||
| <primary> "." <identifier>
|
||
| <primary> "[" <expression> "]"
|
||
| <primary> "[" [<expression>] ":" [<expression>] [":" [<expression>]] "]"
|
||
| <primary> "(" [<argument_list>] ")"
|
||
|
||
<atom> ::= <identifier>
|
||
| "$" <identifier>
|
||
| <literal>
|
||
| "(" <expression> ")"
|
||
| <list_display>
|
||
| <dict_display>
|
||
|
||
/* Estructuras de Datos, Comprensiones y Argumentos */
|
||
<list_display> ::= "[" [<argument_list>] "]"
|
||
| "[" <expression> "for" <identifier> "in" <expression> [<if_clause>] "]"
|
||
<if_clause> ::= "if" <expression>
|
||
<dict_display> ::= "{" [<key_datum_list>] "}"
|
||
<key_datum_list> ::= <key_datum> ( "," <key_datum> )*
|
||
<key_datum> ::= <expression> ":" <expression>
|
||
<argument_list> ::= <expression> ( "," <expression> )*
|
||
|
||
/* Tipo numérico unificado */
|
||
<number> ::= <floatnumber> | <integer>
|
||
|
||
/* Literales (Tipos de Datos Primitivos Soportados) */
|
||
<literal> ::= <stringliteral> | <number> | <boolean> | "None"
|
||
<boolean> ::= "True" | "False"
|
||
<integer> ::= [0-9]+
|
||
<floatnumber> ::= [0-9]+ "." [0-9]* | "." [0-9]+
|
||
|
||
/* Cadenas de Texto con soporte de secuencias de escape */
|
||
<stringliteral> ::= "\"" <text_double> "\"" | "'" <text_single> "'"
|
||
<escape_sequence> ::= "\\" ( "\"" | "'" | "\\" | "n" | "t" | "r" | "0" )
|
||
<text_double> ::= ( [^"\\] | <escape_sequence> )*
|
||
<text_single> ::= ( [^'\\] | <escape_sequence> )*
|
||
<identifier_or_string> ::= <identifier> | <stringliteral>
|
||
|
||
/* Reglas de Comentarios para el Lexer
|
||
El lexer aplica longest-match: /// debe evaluarse ANTES que // */
|
||
<doc_comment> ::= "///" <any_text>
|
||
<line_comment> ::= "//" <any_text>
|
||
<block_comment> ::= "/*" <any_content> "*/"
|
||
<any_text> ::= [^\r\n]*
|
||
<any_content> ::= /* Cualquier secuencia de caracteres que no contenga la subcadena "*/" */
|
||
```
|
||
|
||
# APÉNDICE X: Especificación Léxica de AVAP
|
||
|
||
Este apéndice define las reglas del **analizador léxico (lexer)** del lenguaje AVAP.
|
||
El lexer transforma el código fuente en una secuencia de **tokens**, que posteriormente son consumidos por el parser descrito en la gramática BNF.
|
||
|
||
El análisis léxico sigue el principio de **máxima coincidencia (longest match)**: cuando múltiples reglas pueden coincidir con el mismo texto, se selecciona la coincidencia más larga.
|
||
|
||
---
|
||
|
||
# X.1 Espacios en blanco y separadores
|
||
|
||
Los siguientes caracteres se ignoran excepto cuando forman parte de literales o comentarios.
|
||
|
||
```regex
|
||
WHITESPACE ::= [ \t]+
|
||
EOL ::= \r\n | \n | \r
|
||
```
|
||
|
||
Reglas:
|
||
|
||
- `WHITESPACE` se ignora
|
||
- `EOL` genera el token **EOL**, que actúa como terminador de sentencia
|
||
- AVAP es un lenguaje **orientado a líneas**, por lo que las sentencias no pueden dividirse en múltiples líneas.
|
||
|
||
---
|
||
|
||
# X.2 Comentarios
|
||
|
||
AVAP soporta tres tipos de comentarios. El lexer aplica longest-match, por lo que `///` debe reconocerse **antes** que `//`.
|
||
|
||
## Comentario de documentación (mayor prioridad)
|
||
|
||
```regex
|
||
DOC_COMMENT ::= "///"[^\r\n]*
|
||
```
|
||
|
||
Se utiliza para generar documentación automática o anotaciones de herramientas.
|
||
|
||
Ejemplo:
|
||
|
||
```avap
|
||
/// obtiene el balance del usuario
|
||
```
|
||
|
||
---
|
||
|
||
## Comentario de línea
|
||
|
||
```regex
|
||
LINE_COMMENT ::= "//"[^\r\n]*
|
||
```
|
||
|
||
Ejemplo:
|
||
|
||
```avap
|
||
// comentario
|
||
```
|
||
|
||
El texto se ignora hasta el final de la línea.
|
||
|
||
---
|
||
|
||
## Comentario de bloque
|
||
|
||
```regex
|
||
BLOCK_COMMENT ::= "/*" .*? "*/"
|
||
```
|
||
|
||
Puede abarcar múltiples líneas.
|
||
|
||
Ejemplo:
|
||
|
||
```avap
|
||
/* comentario
|
||
multilinea */
|
||
```
|
||
|
||
---
|
||
|
||
# X.3 Identificadores
|
||
|
||
Los identificadores representan nombres de variables, funciones o parámetros.
|
||
|
||
```regex
|
||
IDENTIFIER ::= [a-zA-Z_][a-zA-Z0-9_]*
|
||
```
|
||
|
||
Ejemplos válidos:
|
||
|
||
```
|
||
x
|
||
user_id
|
||
balanceTotal
|
||
_connector
|
||
```
|
||
|
||
---
|
||
|
||
# X.4 Palabras reservadas
|
||
|
||
Las siguientes palabras están reservadas y **no pueden utilizarse como identificadores**.
|
||
|
||
## Control de flujo
|
||
|
||
```
|
||
if
|
||
else
|
||
end
|
||
startLoop
|
||
endLoop
|
||
try
|
||
exception
|
||
return
|
||
```
|
||
|
||
## Declaración de funciones
|
||
|
||
```
|
||
function
|
||
```
|
||
|
||
## Concurrencia
|
||
|
||
```
|
||
go
|
||
gather
|
||
```
|
||
|
||
## Modularidad
|
||
|
||
```
|
||
include
|
||
import
|
||
```
|
||
|
||
## Operadores lógicos
|
||
|
||
```
|
||
and
|
||
or
|
||
not
|
||
in
|
||
is
|
||
```
|
||
|
||
## Literales
|
||
|
||
```
|
||
True
|
||
False
|
||
None
|
||
```
|
||
|
||
---
|
||
|
||
# X.5 Operadores
|
||
|
||
## Asignación
|
||
|
||
```
|
||
=
|
||
```
|
||
|
||
Token:
|
||
|
||
```
|
||
ASSIGN
|
||
```
|
||
|
||
---
|
||
|
||
## Operadores aritméticos
|
||
|
||
```
|
||
+
|
||
-
|
||
*
|
||
/
|
||
%
|
||
**
|
||
```
|
||
|
||
Tokens:
|
||
|
||
```
|
||
PLUS
|
||
MINUS
|
||
MULT
|
||
DIV
|
||
MOD
|
||
POWER
|
||
```
|
||
|
||
Regla importante:
|
||
|
||
`**` debe evaluarse antes que `*` por la regla de **máxima coincidencia**.
|
||
|
||
---
|
||
|
||
## Operadores de comparación
|
||
|
||
```
|
||
==
|
||
!=
|
||
<
|
||
>
|
||
<=
|
||
>=
|
||
```
|
||
|
||
Tokens:
|
||
|
||
```
|
||
EQ
|
||
NEQ
|
||
LT
|
||
GT
|
||
LTE
|
||
GTE
|
||
```
|
||
|
||
---
|
||
|
||
## Operadores lógicos
|
||
|
||
```
|
||
and
|
||
or
|
||
not
|
||
```
|
||
|
||
Tokens:
|
||
|
||
```
|
||
AND
|
||
OR
|
||
NOT
|
||
```
|
||
|
||
---
|
||
|
||
# X.6 Delimitadores
|
||
|
||
Los siguientes símbolos delimitan estructuras sintácticas.
|
||
|
||
```
|
||
(
|
||
)
|
||
[
|
||
]
|
||
{
|
||
}
|
||
,
|
||
.
|
||
:
|
||
```
|
||
|
||
Tokens:
|
||
|
||
```
|
||
LPAREN
|
||
RPAREN
|
||
LBRACKET
|
||
RBRACKET
|
||
LBRACE
|
||
RBRACE
|
||
COMMA
|
||
DOT
|
||
COLON
|
||
```
|
||
|
||
---
|
||
|
||
# X.7 Literales
|
||
|
||
## Enteros
|
||
|
||
```regex
|
||
INTEGER ::= [0-9]+
|
||
```
|
||
|
||
Ejemplos:
|
||
|
||
```
|
||
0
|
||
10
|
||
999
|
||
```
|
||
|
||
---
|
||
|
||
## Números flotantes
|
||
|
||
```regex
|
||
FLOAT ::= [0-9]+\.[0-9]* | \.[0-9]+
|
||
```
|
||
|
||
Ejemplos:
|
||
|
||
```
|
||
1.0
|
||
3.14
|
||
.5
|
||
```
|
||
|
||
---
|
||
|
||
## Strings
|
||
|
||
AVAP soporta cadenas con comillas simples y dobles, con soporte de secuencias de escape.
|
||
|
||
```regex
|
||
STRING_DOUBLE ::= "\"" ( [^"\\] | ESCAPE_SEQ )* "\""
|
||
STRING_SINGLE ::= "'" ( [^'\\] | ESCAPE_SEQ )* "'"
|
||
ESCAPE_SEQ ::= "\\" ( '"' | "'" | "\\" | "n" | "t" | "r" | "0" )
|
||
```
|
||
|
||
Ejemplos:
|
||
|
||
```
|
||
"hola"
|
||
'texto'
|
||
"https://api.com"
|
||
```
|
||
|
||
Secuencias de escape soportadas:
|
||
|
||
| Secuencia | Significado |
|
||
|-----------|-------------------|
|
||
| `\"` | Comilla doble |
|
||
| `\'` | Comilla simple |
|
||
| `\\` | Barra invertida |
|
||
| `\n` | Salto de línea |
|
||
| `\t` | Tabulación |
|
||
| `\r` | Retorno de carro |
|
||
| `\0` | Carácter nulo |
|
||
|
||
> **Nota:** `\n` dentro de un string es un carácter de datos, no un terminador de sentencia. El EOL físico sigue siendo el único terminador.
|
||
|
||
---
|
||
|
||
# X.8 Literales booleanos
|
||
|
||
Tokens:
|
||
|
||
```
|
||
True
|
||
False
|
||
```
|
||
|
||
---
|
||
|
||
# X.9 Literal nulo
|
||
|
||
Token:
|
||
|
||
```
|
||
None
|
||
```
|
||
|
||
---
|
||
|
||
# X.10 Operador de desreferenciación
|
||
|
||
AVAP permite acceder al valor de una variable utilizando el prefijo `$`.
|
||
|
||
Ejemplo:
|
||
|
||
```avap
|
||
addVar(copia, $original)
|
||
```
|
||
|
||
Token:
|
||
|
||
```
|
||
DEREF ::= $
|
||
```
|
||
|
||
---
|
||
|
||
# X.11 Orden de precedencia léxica
|
||
|
||
Para evitar ambigüedades, el lexer debe aplicar el principio **longest match first**.
|
||
|
||
Orden obligatorio:
|
||
|
||
1. comentarios (`///` antes que `//`, luego `/* */`)
|
||
2. whitespace
|
||
3. palabras reservadas
|
||
4. identificadores
|
||
5. números flotantes
|
||
6. enteros
|
||
7. strings
|
||
8. operadores compuestos (`**`, `==`, `<=`, `>=`, `!=`)
|
||
9. operadores simples
|
||
10. delimitadores
|
||
|
||
---
|
||
|
||
# X.12 Separación formal: nivel léxico vs nivel sintáctico
|
||
|
||
```
|
||
NIVEL LÉXICO — produce tokens: IDENTIFIER, INTEGER, FLOAT, STRING,
|
||
operadores, delimitadores, EOL, palabras reservadas.
|
||
|
||
NIVEL SINTÁCTICO — consume tokens: construye el AST según las reglas BNF
|
||
de las Secciones I–IX.
|
||
```
|
||
|
||
El Apéndice X cubre el nivel léxico. Las Secciones I–IX cubren el nivel sintáctico.
|
||
|
||
---
|
||
|
||
# X.13 Tokens producidos por el lexer
|
||
|
||
El lexer produce los siguientes tokens:
|
||
|
||
```
|
||
IDENTIFIER
|
||
INTEGER
|
||
FLOAT
|
||
STRING
|
||
|
||
ASSIGN
|
||
PLUS
|
||
MINUS
|
||
MULT
|
||
DIV
|
||
MOD
|
||
POWER
|
||
|
||
EQ
|
||
NEQ
|
||
LT
|
||
GT
|
||
LTE
|
||
GTE
|
||
|
||
AND
|
||
OR
|
||
NOT
|
||
IN
|
||
IS
|
||
|
||
LPAREN
|
||
RPAREN
|
||
LBRACKET
|
||
RBRACKET
|
||
LBRACE
|
||
RBRACE
|
||
COMMA
|
||
DOT
|
||
COLON
|
||
|
||
DEREF
|
||
|
||
True
|
||
False
|
||
None
|
||
|
||
EOL
|
||
```
|
||
|
||
---
|
||
|
||
# X.14 Elementos ignorados por el lexer
|
||
|
||
Los siguientes elementos se descartan durante el análisis léxico:
|
||
|
||
```
|
||
WHITESPACE
|
||
LINE_COMMENT
|
||
DOC_COMMENT
|
||
BLOCK_COMMENT
|
||
```
|
||
|
||
Estos tokens no son enviados al parser.
|
||
|
||
|
||
# XI.1 Modelo de Memoria y Resolución de Variables
|
||
|
||
AVAP utiliza un modelo de memoria basado en **tres tipos de ámbitos (scopes)**:
|
||
|
||
```
|
||
Global Scope
|
||
Main Local Scope
|
||
Function Scope
|
||
```
|
||
|
||
Cada tipo de ámbito tiene reglas estrictas de visibilidad.
|
||
|
||
---
|
||
|
||
# XI.1.1 Global Scope
|
||
|
||
El **Global Scope** contiene variables declaradas como globales y es accesible desde cualquier parte del programa.
|
||
|
||
Propiedades:
|
||
|
||
- existe durante toda la vida del proceso del intérprete
|
||
- es visible desde el flujo principal
|
||
- es visible desde todas las funciones
|
||
- es visible desde goroutines
|
||
|
||
Las variables globales actúan como **estado compartido del programa**.
|
||
|
||
---
|
||
|
||
# XI.1.2 Main Local Scope
|
||
|
||
El **Main Local Scope** corresponde al flujo de ejecución principal del script, fuera de cualquier función.
|
||
|
||
Ejemplo:
|
||
|
||
```
|
||
x = 10
|
||
y = 20
|
||
```
|
||
|
||
Estas variables son **locales del flujo principal**.
|
||
|
||
Reglas:
|
||
|
||
- son accesibles dentro del flujo principal
|
||
- **no son accesibles desde funciones**
|
||
- **no son accesibles desde goroutines**
|
||
- desaparecen cuando finaliza la ejecución del script
|
||
|
||
Esto evita dependencias implícitas entre funciones y el flujo principal.
|
||
|
||
---
|
||
|
||
# XI.1.3 Function Scope
|
||
|
||
Cada vez que se invoca una función:
|
||
|
||
```
|
||
function nombre(parametros)
|
||
```
|
||
|
||
el motor crea un **Function Scope independiente**.
|
||
|
||
Este ámbito contiene:
|
||
|
||
- parámetros de la función
|
||
- variables creadas dentro de la función
|
||
- resultados intermedios
|
||
|
||
Propiedades:
|
||
|
||
- solo es visible dentro de esa función
|
||
- no es visible desde el exterior
|
||
- se destruye cuando la función termina
|
||
|
||
---
|
||
|
||
# XI.1.4 Resolución de variables
|
||
|
||
La resolución de variables sigue el siguiente orden jerárquico:
|
||
|
||
```
|
||
1. Function Scope
|
||
2. Global Scope
|
||
```
|
||
|
||
El **Main Local Scope no es visible dentro de funciones**.
|
||
|
||
Si una variable no existe en los scopes visibles, el motor produce un **error de ejecución**.
|
||
|
||
---
|
||
|
||
# XI.1.5 Aislamiento entre funciones
|
||
|
||
Cada invocación de función crea un **scope independiente**.
|
||
|
||
Ejemplo:
|
||
|
||
```
|
||
function ejemplo()
|
||
{
|
||
x = 10
|
||
}
|
||
```
|
||
|
||
La variable `x`:
|
||
|
||
- solo existe dentro de esa ejecución de la función
|
||
- no es visible desde otras funciones
|
||
- no es visible desde el flujo principal
|
||
|
||
---
|
||
|
||
# XI.1.6 Acceso desde goroutines
|
||
|
||
Las goroutines creadas mediante:
|
||
|
||
```
|
||
go funcion()
|
||
```
|
||
|
||
siguen las mismas reglas de scope que una función normal.
|
||
|
||
Por lo tanto:
|
||
|
||
- pueden acceder a **Global Scope**
|
||
- pueden acceder a su propio **Function Scope**
|
||
- **no pueden acceder al Main Local Scope** |