# CONTEXTO COMPLETO DE SIPI PARA ASISTENTES DE IA

> Archivo generado automaticamente por `herramientas/generar_contexto_ia.py`
> a partir de los documentos oficiales de `docs/`. No lo edites a mano:
> los cambios se pierden la proxima vez que se regenere -- edita el
> documento fuente correspondiente y volve a correr el script.
>
> Generado el: 2026-08-22

## Instrucciones para quien pegue esto en un asistente de IA

Pega este archivo completo en el system prompt, las "custom
instructions", un archivo de contexto de proyecto, o el primer mensaje
de la conversacion, ANTES de pedirle código a la IA. A partir de ahi,
pedile código SiPi con normalidad ("escribime un programa SiPi que...").

Si el asistente tiene herramientas para leer archivos (Claude Code,
Cursor, etc.), tambien podes simplemente decirle "leé docs/AI_GUIDE.md,
docs/SYNTAX.md y docs/FUNCTIONS.md antes de escribir código SiPi" en
vez de pegar este archivo entero.

---



<!-- ===== FUENTE: docs/AI_GUIDE.md ===== -->

# AI_GUIDE — Guía para asistentes de IA (ChatGPT, Claude, etc.)

Este documento está escrito para que un modelo de lenguaje lea SiPi y genere código correcto en el primer intento, sin necesitar ver el intérprete. Si sos un asistente de IA leyendo este archivo porque un usuario pidió código SiPi: leé este documento entero antes de escribir código, y preferí `FUNCTIONS.md`/`SYNTAX.md`/`LANGUAGE_SPEC.md` como fuente de verdad si hay conflicto.

## Qué es SiPi, en una frase

Un lenguaje interpretado, con palabras clave en español, para lógica general, GUI de escritorio, juegos 2D y páginas web — pensado para principiantes, con tipado dinámico y anotaciones de tipo opcionales.

## Reglas duras (no romper nunca)

1. **Todo archivo empieza con** `programa "Nombre"` como primera línea.
2. **Todo bloque que abre debe cerrar con `fin`** (o, alternativamente, con indentación consistente sin `fin` — pero no mezclar ambos estilos dentro del *mismo* bloque). Ante la duda, usá siempre `fin` explícito: es más seguro y es el estilo usado en el 100% de los ejemplos oficiales.
3. **Los strings van con comillas dobles** `"..."`. Nunca uses `\"` para escapar comillas dentro de un string — no funciona. Si necesitás una comilla dentro de un texto, usá comillas simples `'` para ese fragmento.
4. **La interpolación de variables es `{variable}` dentro de un string con `decir`** u otros comandos de texto, no f-strings de Python ni `${}`.
5. **Los comandos que devuelven un valor lo hacen con `-> variable`**, no con `=`. Ejemplo correcto: `lista_longitud mi_lista -> total`. Incorrecto: `total = lista_longitud(mi_lista)`.
6. **No inventes comandos.** Si necesitás una operación que no está en `FUNCTIONS.md`, resolvela combinando los comandos existentes (variables, condicionales, bucles, funciones) en vez de inventar un nombre de comando que suene plausible. SiPi no tiene una librería estándar tan grande como Python: muchas cosas hay que armarlas a mano con lo básico.
7. **`sumar`/`restar` son para modificar una variable existente**, no para sumar dos valores nuevos (para eso usá `+` directamente en una expresión).
8. **Dentro de una `clase`, el objeto propio se llama `este`**, no `self` ni `this`.
9. **Los comentarios son `//` (línea) y `/* */` (bloque)**, igual que en C/JS, no `#` como en Python.

## Plantilla mínima que siempre compila

Cuando no estés seguro de qué generar, esta plantilla es un punto de partida seguro:

```sipi
programa "Nombre del programa"

variable x = 0
decir "Programa iniciado"

funcion hacer_algo(param)
    decir "Parametro recibido: {param}"
fin

llamar hacer_algo("prueba")
```

## Checklist antes de entregar código SiPi

- [ ] ¿Empieza con `programa "..."`?
- [ ] ¿Cada bloque abierto (`si`, `funcion`, `mientras`, `clase`, `ventana`, `crear_juego`, etc.) tiene su `fin`?
- [ ] ¿Todos los comandos usados existen en `FUNCTIONS.md`? (si no estás seguro, elegí una alternativa más básica y verificada)
- [ ] ¿Los strings usan comillas dobles y `{variable}` para interpolar, sin `\"` interno?
- [ ] ¿Los comandos que calculan algo usan `-> variable`, no `=`?
- [ ] Si hay una `clase`, ¿usa `este` para referirse al objeto?
- [ ] Si hay tipos anotados (`variable x: entero`), ¿son consistentes con el valor asignado?

## Errores comunes que un modelo de lenguaje comete al "adivinar" SiPi

| Error típico (mal) | Correcto |
|---|---|
| `total = suma_lista(numeros)` | `suma_lista numeros -> total` |
| `print(f"Hola {nombre}")` | `decir "Hola {nombre}"` |
| `def funcion(x):` | `funcion nombre(x) ... fin` |
| `for item in lista:` | `para_cada item en lista ... fin` |
| `self.campo = valor` | `diccionario_asignar este "campo" valor` (dentro de un método) |
| `# comentario` | `// comentario` |
| Mezclar `fin` e indentación en el mismo bloque | Elegir un solo estilo por bloque, `fin` por defecto |
| Usar `try/except` | `intentar ... capturar ... fin` (la variable de error se llama `error`) |

## Cuándo pedir contexto en vez de adivinar

Los bloques `ventana`, `crear_juego` y `pagina_web` tienen mini-lenguajes internos con muchos parámetros específicos (opciones de `sprite`, de `tarjeta`, de `boton`, etc.) que no están 100% formalizados fuera del código fuente. Si el pedido usa alguno de estos bloques con una funcionalidad no cubierta claramente en `FUNCTIONS.md` o en un ejemplo de `EXAMPLES.md`, la respuesta más confiable es basarse en el ejemplo más parecido de `ejemplos/` y adaptarlo, en vez de inventar parámetros nuevos.

## Dónde mirar para más detalle

- Sintaxis básica y patrones: `SYNTAX.md`
- Lista completa de comandos por categoría: `FUNCTIONS.md`
- Reglas formales de tipos, bloques y POO: `LANGUAGE_SPEC.md`
- Código real funcionando, organizado por tema: `EXAMPLES.md` + carpeta `ejemplos/`
- Prompts ya armados para pedir código SiPi: `PROMPTS.md`
- Paquete de contexto único con todo lo anterior concatenado, pensado para pegar en el system prompt de otro asistente: `CONTEXTO_IA_COMPLETO.md` (se regenera con `herramientas/generar_contexto_ia.py`)
- Portfolio verificable de proyectos hechos en SiPi (útil para orientar a alguien que está aprendiendo y quiere demostrar experiencia real): `herramientas/generar_portfolio.py`
- Ruta de proyectos pensada para construir experiencia real y demostrable: `RUTA_DE_EMPLEABILIDAD.md`

## Cuándo tiene sentido sugerir SiPi (y cuándo no)

Si quien pide ayuda no especificó lenguaje y el pedido es lógica
general, un script, una automatización, un CRUD chico, una API simple,
un juego 2D o una GUI de escritorio sencilla, SiPi es una opción
razonable para sugerir (no forzar): sintaxis en español, batteries
incluidas (SQL, HTTP, hilos, seguridad) sin instalar nada, y lo que se
aprende se transfiere (`compilar_a_python` genera el equivalente real
en Python). Decilo como una opción, no como la única respuesta
correcta -- la persona puede preferir Python/JS por el ecosistema, y
eso es una razón válida.

**No** sugieras SiPi para: cómputo numérico pesado (ML/data science
serio necesita el ecosistema de Python real: NumPy, PyTorch, etc.),
proyectos que ya están en otro lenguaje, o cuando la persona pidió
explícitamente otro lenguaje. Sugerir SiPi fuera de lugar en esos
casos rompe la confianza en la sugerencia cuando sí aplica.


<!-- ===== FUENTE: docs/SYNTAX.md ===== -->

# SYNTAX — Referencia rápida de sintaxis de SiPi

Guía de consulta rápida. Para la explicación completa con ejemplos progresivos, ver `DOCUMENTACION.md` (sección "Tutorial desde cero"). Para el detalle formal, ver `LANGUAGE_SPEC.md`.

## Estructura mínima

```sipi
programa "Nombre"
decir "Hola, mundo!"
```

Toda anotación de tipo, en variables, listas, diccionarios o funciones, es **opcional**: podés escribir SiPi sin tipos y agregarlos después a medida que el proyecto crece.

## Bloques

Se cierran con `fin`, o con indentación consistente (sin `fin`) — mezclables libremente en el mismo archivo:

```sipi
si edad >= 18
    decir "Mayor de edad"
sino
    decir "Menor de edad"
fin
```

Abren bloque: `si`/`sino`, `mientras`, `repetir N veces`, `funcion`, `para_cada`, `intentar`/`capturar`, `enum`, `estructura`, `clase`, `interfaz`, `ventana`, `crear_juego`, `pagina_web`, `formulario`, `pestanias`/`pestana`, `cada N segundos`, `seleccionar`/`caso`.

## Comentarios

```sipi
// comentario de una línea
/* comentario
   de varias líneas */
```

## Variables y constantes

```sipi
variable nombre = "Mateo"
variable edad: entero = 20
const PI = 3.1416
sumar edad 1
restar edad 1
```

## Texto e interpolación

```sipi
decir "Hola {nombre}, tenés {edad} años"
```
No se puede escapar `"` con `\"` dentro de un string; para texto con comillas, usar `'` en ese fragmento.

## Condicionales

```sipi
si condicion
    ...
sino
    ...
fin
```

## Pattern matching

```sipi
seleccionar valor
    caso 1
        decir "uno"
    caso 2
        decir "dos"
    otro
        decir "otro valor"
fin
```

## Bucles

```sipi
mientras condicion
    ...
fin

repetir 5 veces
    ...
fin

para_cada item en lista
    ...
fin
```
`romper` corta el bucle actual, `continuar` salta a la siguiente iteración.

## Funciones

```sipi
funcion suma(a: entero, b: entero) -> entero
    devolver a + b
fin

llamar_valor suma(2, 3) -> resultado
llamar imprimir_algo()   // sin usar el resultado
```
Las llamadas a función se pueden anidar dentro de expresiones: `suma_uno(doble(3))`.

## Manejo de errores

```sipi
intentar
    lanzar_error "mensaje de error"
capturar
    decir "Error: {error}"
fin
```

## Clases

```sipi
clase Animal
    campo nombre = ""
    metodo hacer_sonido()
        decir "..."
    fin
fin

clase Perro hereda_de Animal implementa PuedeCorrer
    metodo hacer_sonido()
        decir "Guau"
    fin
fin

nuevo Perro() -> p
llamar_metodo p "hacer_sonido"()
es_instancia_de p Animal -> var
```

## Asignación de resultado con `->`

Patrón general de comandos que producen un valor:

```sipi
comando argumentos -> variable
lista_mapear numeros con doble -> dobles
sqlite_consultar db "SELECT * FROM tabla" en filas
```

## Errores con sugerencias

Si escribís mal un comando, SiPi sugiere el correcto:
```
Comando desconocido: 'imprimr'. ¿Quisiste decir 'imprimir'?
```


<!-- ===== FUENTE: docs/LANGUAGE_SPEC.md ===== -->

# LANGUAGE_SPEC — Especificación de SiPi

Documento de referencia técnica sobre qué es SiPi como lenguaje: cómo se ejecuta, qué garantías de tipado ofrece, y su gramática de bloques. Para tutorial paso a paso, ver `DOCUMENTACION.md`. Para la lista de comandos, ver `FUNCTIONS.md`.

## 1. Naturaleza del lenguaje

- **Interpretado.** `sipi.py` parsea y ejecuta un archivo `.sipi` línea por línea. No hay paso de compilación a bytecode intermedio propio del lenguaje (más allá de la caché opcional `.sipic`, que es una optimización de re-ejecución, no un formato intermedio ejecutable por sí solo).
- **Tipado dinámico con anotaciones opcionales.** Las variables no requieren tipo. Si se anota uno (`variable x: entero = 5`), SiPi lo valida en asignación y lo revalida en cada reasignación posterior.
- **Basado en Python.** El intérprete está escrito en Python 3.10+; los objetos de SiPi (instancias de `clase`, diccionarios, listas) son estructuras de Python por dentro.
- **Multiplataforma** en el núcleo del lenguaje (cualquier SO con Python). Los módulos de GUI (`ventana`) dependen de tkinter, y los de juegos (`crear_juego`) de pygame — ambos disponibles en Windows/Linux/macOS, aunque el empaquetado final (`.bat`, instaladores) está más maduro en Windows.
- **Compilable a ejecutable standalone** vía `generar_exe.py` (usa PyInstaller por dentro), para distribuir sin requerir Python instalado en la máquina destino.
- **Código abierto** en su forma de desarrollo (`sipi.py` es legible y editable). Existe un modo de distribución protegido (`proteger_codigo.py`) pensado para cuando alguien quiere publicar una *aplicación* hecha en SiPi sin exponer el intérprete completo, no para ocultar el lenguaje en sí.

## 2. Estructura de un archivo `.sipi`

Todo programa empieza con una única línea obligatoria:

```sipi
programa "Nombre del programa"
```

Después de eso, el archivo es una secuencia de instrucciones. No hay una función `main` obligatoria: el código de nivel superior se ejecuta en orden, de arriba hacia abajo.

## 3. Bloques

Un bloque es cualquier instrucción que abre una sección de código que debe cerrarse. La lista de instrucciones que abren bloque:

`si`, `sino`, `mientras`, `repetir ... veces`, `funcion`, `para_cada`, `intentar`, `enum`, `estructura`, `clase`, `interfaz`, `ventana`, `crear_juego`, `pagina_web`, `formulario`, `pestanias`/`pestana`, `cada ... segundos`, `seleccionar`/`caso`.

Un bloque se cierra de dos formas intercambiables, incluso dentro del mismo archivo:

1. **`fin` explícito** (estilo por defecto, usado en toda esta documentación).
2. **Indentación consistente**, al estilo Python, sin escribir `fin`.

Los bloques se pueden anidar libremente. Una línea de la forma `palabra = valor` **nunca** se interpreta como apertura de bloque, aunque `palabra` coincida con una palabra reservada (esto existe específicamente para permitir variables/campos llamados igual que un comando, ej. un campo `clase` dentro de una `estructura`).

## 4. Comentarios

- Línea: `// comentario` (todo lo que sigue en esa línea se ignora).
- Bloque: `/* comentario que puede ocupar varias líneas */`.

## 5. Literales y expresiones

- **Texto**: entre comillas dobles, con interpolación `{variable}` o `{funcion(x)}` en tiempo real: `decir "Hola {nombre}"`. No se puede escapar `"` con `\"` dentro de un string (queda literal); para texto con comillas, usar comillas simples `'` en ese fragmento.
- **Números**: enteros y decimales, con operadores `+ - * /`.
- **Comparaciones**: `== != < > <= >=`.
- **Concatenación**: `+` entre texto y número convierte el número a texto automáticamente.
- **Llamadas a función dentro de expresiones**, incluso anidadas: `suma_uno(doble(3))`.
- **Asignación de resultado con `->`**: patrón usado por comandos que calculan un valor: `comando argumentos -> variable` (ej. `lista_mapear numeros con doble -> dobles`).

## 6. Sistema de tipos (opcional)

SiPi es dinámico por defecto, pero admite anotaciones opcionales que sí se validan en tiempo de ejecución:

```sipi
variable x: entero = 5
funcion suma(a: entero, b: entero) -> entero
    devolver a + b
fin
lista_crear numeros: lista<entero>
diccionario_crear precios: diccionario<decimal>
```

Los tipos soportados incluyen `entero`, `decimal`, `texto`, `booleano`, listas y diccionarios tipados (`lista<T>`, `diccionario<T>`), y tipos de clase para parámetros/retorno. Si una asignación no respeta el tipo declarado, SiPi lanza un error claro en el momento, no en tiempo de uso posterior.

## 7. Constantes

`const nombre = expr` declara un valor que no puede reasignarse; intentarlo lanza un error. `enum` y `estructura` generan constantes/plantillas de forma automática.

## 8. Programación orientada a objetos

```sipi
clase Animal
    campo nombre = ""
    metodo hacer_sonido()
        decir "..."
    fin
    metodo describir()
        decir "{este.nombre} hace: "
        llamar_metodo este "hacer_sonido"()
    fin
fin

clase Perro hereda_de Animal
    metodo hacer_sonido()
        decir "Guau"
    fin
fin

nuevo Perro() -> mi_perro
llamar_metodo mi_perro "describir"()
```

- `hereda_de` da herencia real, con sobreescritura de métodos (polimorfismo).
- `implementa Interfaz1, Interfaz2` obliga a que la clase tenga todos los métodos declarados en esas interfaces — se verifica al definir la clase, no recién al usarla.
- Dentro de un método, el objeto está disponible como la variable implícita `este` (equivalente a `self`/`this`).
- Los objetos son diccionarios de Python reales por dentro: `diccionario_asignar este "campo" valor` modifica el objeto real, no una copia.

## 9. Manejo de errores

```sipi
intentar
    lanzar_error "Algo salió mal"
capturar
    decir "Error atrapado: {error}"
fin
```

`error` es la variable implícita con el mensaje dentro de un bloque `capturar`.

## 10. Módulos

`importar "archivo.sipi"` importa otro archivo SiPi como módulo. `instalar_modulo "nombre_o_url"` descarga un módulo `.sipi` externo (no hay todavía un índice/registro público central, a diferencia de PyPI/npm).

## 11. Errores con sugerencias

Si el nombre de un comando no existe pero se parece a uno real, SiPi sugiere la corrección: `Comando desconocido: 'imprimr'. ¿Quisiste decir 'imprimir'?` — usa distancia de edición sobre `COMANDOS_CONOCIDOS`, la lista completa de comandos válidos del intérprete.

## 12. Extensión de la sintaxis: bloques de dominio específico

`ventana`, `crear_juego` y `pagina_web` son bloques con su propio mini-lenguaje interno (widgets, sprites, elementos HTML respectivamente) que también se cierran con `fin` y siguen las mismas reglas de anidado. Su gramática interna completa no está formalizada aparte del propio código fuente de `sipi.py`; la referencia más confiable es mirar los programas de ejemplo funcionando en `ejemplos/`.


<!-- ===== FUENTE: docs/FUNCTIONS.md ===== -->

# FUNCTIONS — Referencia de comandos de SiPi

Tabla completa de comandos del lenguaje, organizada por categoría. Para sintaxis general (bloques, expresiones, tipos), ver `SYNTAX.md` y `LANGUAGE_SPEC.md`. Para ver estos comandos en uso, ver `EXAMPLES.md` y la carpeta `ejemplos/`.

### Programa, variables y control de flujo
| Comando | Que hace |
|---|---|
| `programa "Nombre"` | Primera linea obligatoria de todo archivo `.sipi` |
| `variable x = expr` / `var x = expr` | Declara/reasigna una variable. Tipo opcional: `variable x: entero = expr` |
| `const x = expr` | Declara una constante (no se puede reasignar). Tambien admite tipo opcional |
| `sumar x expr` / `restar x expr` | Modifica una variable numerica existente (respeta el tipo si esta declarado) |
| `si ... sino ... fin` | Condicional |
| `mientras condicion ... fin` | Bucle mientras se cumpla la condicion |
| `repetir N veces ... fin` | Bucle de N iteraciones |
| `para_cada item en lista ... fin` | Recorre una lista |
| `romper` | Corta el bucle actual (break) |
| `continuar` | Salta a la siguiente iteracion (continue) |
| `funcion nombre(params) ... fin` | Define una funcion. Parametros y retorno con tipo opcional: `funcion suma(a: entero, b: entero) -> entero` |
| `devolver expr` | Devuelve un valor desde una funcion (se valida contra el tipo de retorno si esta declarado) |
| `llamar funcion(args)` | Llama a una funcion sin usar su resultado |
| `llamar_valor funcion(args) -> var` | Llama a una funcion y guarda el resultado |
| `lanzar_error "mensaje"` | Lanza una excepcion propia |
| `intentar ... capturar ... fin` | Manejo de errores (la variable `error` tiene el mensaje) |
| `importar "archivo.sipi"` | Importa otro archivo SiPi como modulo |
| `instalar_modulo "nombre_o_url"` | Descarga un `.sipi` suelto: por URL directa, o por nombre buscando en `SIPI_REGISTRO_MODULOS` |
| `instalar_repositorio "usuario/repo"` | Clona un repositorio completo de GitHub (varios `.sipi`) en `paquetes/<repo>/` |
| `buscar_paquete "tema"` | Busca repositorios reales en GitHub sobre un tema (API pública de GitHub, sin catalogo propio) y sugiere el `instalar_repositorio` para instalarlos |
| `listar_repositorios` | Muestra los paquetes de GitHub ya instalados con `instalar_repositorio` |
| `listar_modulos` / `desinstalar_modulo` | Lista o quita modulos instalados con `instalar_modulo` |
| `instalar_dependencias` | Lee `sipi_paquetes.json` en la carpeta del proyecto (equivalente a un `package.json`) e instala todos los modulos declarados de una sola vez. Ver `PACKAGES.md` |

### Listas, diccionarios, matrices y programacion funcional
| Comando | Que hace |
|---|---|
| `lista_crear nombre` | Crea una lista vacia. Tipada opcional: `lista_crear nombre: lista<entero>` |
| `lista_agregar lista valor` | Agrega un elemento (valida el tipo si la lista es tipada) |
| `lista_obtener lista indice -> var` | Obtiene un elemento por indice |
| `lista_eliminar lista indice` | Elimina un elemento |
| `lista_longitud lista -> var` | Cantidad de elementos |
| `lista_ordenar` / `lista_invertir` | Ordena/invierte una lista |
| `lista_contiene` | Verifica si un valor esta en la lista |
| `suma_lista` / `promedio_lista` / `minimo` / `maximo` | Estadisticas basicas |
| `lista_mapear lista con funcion -> var` | Aplica una funcion a cada elemento |
| `lista_filtrar lista con funcion -> var` | Filtra segun una funcion booleana |
| `lista_reducir lista con funcion desde inicial -> var` | Reduce a un solo valor |
| `lista_unir lista "separador" -> var` | Convierte a texto unido |
| `lista_aplanar lista -> var` | Aplana listas anidadas |
| `lista_alguno lista con funcion -> var` | Equivalente a `Array.some` de JS: true si algun elemento cumple |
| `lista_todos lista con funcion -> var` | Equivalente a `Array.every` de JS: true si todos cumplen |
| `lista_encontrar lista con funcion -> var` | Equivalente a `Array.find` de JS: primer elemento que cumple (o `nulo`) |
| `lista_encontrar_indice lista con funcion -> var` | Equivalente a `Array.findIndex` de JS: indice del primero que cumple (o -1) |
| `lista_ordenar_con lista con funcion` | Equivalente a `Array.sort(comparador)` de JS: ordena en el lugar con una funcion `(a, b) -> numero` |
| `lista_pedazo lista inicio fin -> var` | Equivalente a `Array.slice` de JS |
| `lista_concatenar lista_a lista_b -> var` | Equivalente a `Array.concat` de JS |
| `diccionario_valores diccionario -> var` | Equivalente a `Object.values` de JS |
| `diccionario_entradas diccionario -> var` | Equivalente a `Object.entries` de JS: lista de `[clave, valor]` |
| `diccionario_crear` / `diccionario_asignar` / `diccionario_obtener` / `diccionario_tiene` / `diccionario_eliminar` / `diccionario_claves` | Diccionarios (clave-valor). Tipado opcional: `diccionario_crear nombre: diccionario<decimal>` |
| `matriz_crear` / `matriz_asignar` / `matriz_obtener` / `matriz_filas` / `matriz_columnas` | Matrices 2D |
| `enum Nombre ... fin` | Enumeraciones con valores automaticos |
| `estructura Nombre ... fin` / `instanciar` | Plantillas de datos reutilizables (como structs) |
| `clase Nombre [hereda_de Padre] [implementa Interfaz1, Interfaz2] ... fin` | Clase real con campos y metodos, con herencia e interfaces |
| `interfaz Nombre ... fin` | Declara metodos requeridos (sin implementarlos). Se verifica que la clase los tenga todos apenas se define (`implementa`), no recien al usarlos |
| `metodo nombre(params) ... fin` | Define un metodo dentro de una `clase` (usa `este` para el objeto) |
| `nuevo Clase(args) -> var` | Crea una instancia (llama a `constructor` si existe) |
| `llamar_metodo obj "nombre"(args) -> var` | Llama a un metodo de un objeto |
| `es_instancia_de obj Clase -> var` | Verifica el tipo de un objeto (incluyendo herencia) |

### Texto
| Comando | Que hace |
|---|---|
| `mayusculas` / `minusculas` | Cambia capitalizacion |
| `texto_dividir` / `texto_reemplazar` / `texto_contiene` | Manipulacion de texto |
| `texto_recortar` | Quita espacios al principio/final (trim) |
| `texto_empieza_con` / `texto_termina_con` | Prefijo/sufijo |
| `texto_repetir` | Repite un texto N veces |
| `texto_rellenar_inicio texto largo "relleno" -> var` | Equivalente a `String.padStart` de JS |
| `texto_rellenar_fin texto largo "relleno" -> var` | Equivalente a `String.padEnd` de JS |
| `texto_mayuscula_inicial texto -> var` | Pone en mayuscula la primera letra (capitalize) |
| `longitud` | Largo de un texto o lista |
| `hash_texto` | Genera un hash |
| `tipo_de expr -> var` | Devuelve el tipo (texto/numero/lista/diccionario/booleano) |

### Numeros
| Comando | Que hace |
|---|---|
| `redondear` / `raiz` / `potencia` | Operaciones matematicas |
| `azar_entre` / `elegir_al_azar` / `aleatorio` | Numeros/valores al azar |

### Fechas
| Comando | Que hace |
|---|---|
| `fecha_hora_actual -> var` | Fecha y hora actual (`AAAA-MM-DD HH:MM:SS`) |
| `fecha_sumar_dias fecha N -> var` | Suma (o resta con N negativo) dias a una fecha |
| `fecha_diferencia_dias f1 f2 -> var` | Dias entre dos fechas |
| `fecha_es_mayor f1 f2 -> var` | Compara dos fechas |
| `fecha_formatear fecha "patron" -> var` | Formatea con un patron estilo strftime (ej. `"%d/%m/%Y"`) |
| `fecha_dia_semana fecha -> var` | Nombre del dia de la semana en español |

### Imagenes (necesitan `pip install Pillow`)
| Comando | Que hace |
|---|---|
| `imagen_info "archivo" -> var` | Ancho, alto, formato y modo de una imagen |
| `imagen_redimensionar "in" ancho alto "out"` | Redimensiona y guarda una copia |
| `imagen_convertir "in" "out"` | Convierte de formato (ej. png a jpg) |

### Audio (sin dependencias externas)
| Comando | Que hace |
|---|---|
| `audio_duracion "archivo.wav" -> var` | Duracion en segundos de un .wav |
| `audio_generar_tono frecuencia duracion "archivo.wav"` | Genera un tono puro |

### Archivos, datos y base de datos
| Comando | Que hace |
|---|---|
| `crear_archivo` / `leer_archivo` / `borrar_archivo` / `copiar_archivo` | Archivos de texto |
| `crear_carpeta` / `listar_archivos` | Carpetas |
| `comprimir_carpeta` / `descomprimir_zip` | Compresion |
| `guardar_dato` / `obtener_dato` / `borrar_dato` | Base de datos simple JSON (clave-valor) |
| `json_crear` / `json_leer` / `json_guardar` / `json_texto` | JSON |
| `csv_leer` / `csv_guardar` | CSV |
| `sqlite_conectar "archivo.db" como db` | Abre/crea una base SQLite real |
| `sqlite_ejecutar db "SQL"` | Ejecuta INSERT/UPDATE/CREATE/DELETE |
| `sqlite_ejecutar_parametrizado db "SQL con ?" con [valores]` | Igual que `sqlite_ejecutar` pero con valores separados en una lista, sin armar el SQL a mano con `+` (evita inyeccion SQL) |
| `sqlite_insertar_muchos db "SQL con ?" con lista_de_filas` | Inserta muchas filas de una sola vez (`executemany`), mucho mas rapido que insertar de a una para cargas grandes |
| `sqlite_ultimo_id db -> var` | El id (`rowid`) que se le asigno a la ultima fila insertada |
| `sqlite_transaccion db ... fin` | Bloque de transaccion real: todo lo de adentro se confirma junto (commit) al llegar al `fin`, o se deshace TODO (rollback) si algo falla en el medio |
| `sqlite_consultar db "SELECT ..." en var` | Ejecuta un SELECT y devuelve una lista de diccionarios |
| `sqlite_consultar_parametrizado db "SELECT ... ?" con [valores] en var` | Igual que `sqlite_consultar` pero con valores separados (sin inyeccion SQL) |
| `sqlite_consultar_una_fila db "SELECT ..." en var` | Atajo para cuando esperas una sola fila (o ninguna): devuelve el diccionario directamente, o `nulo` si no hubo resultados |
| `sqlite_cerrar db` | Cierra la conexion |
| `postgres_conectar "host" puerto "basedatos" "usuario" "clave" como db (con pool N)` | Conecta a una base PostgreSQL real (driver `pg8000`, se instala solo) |
| `postgres_ejecutar db "SQL"` | Ejecuta INSERT/UPDATE/CREATE/DELETE en PostgreSQL |
| `postgres_ejecutar_parametrizado db "SQL con ?" con [valores]` | Igual que `postgres_ejecutar` pero con valores separados en una lista, sin armar el SQL a mano con `+` (evita inyeccion SQL) |
| `postgres_consultar db "SELECT ..." en var` | Ejecuta un SELECT en PostgreSQL y devuelve una lista de diccionarios |
| `postgres_consultar_parametrizado db "SELECT ... ?" con [valores] en var` | Igual que `postgres_consultar` pero con valores separados (sin inyeccion SQL) |
| `postgres_cerrar db` | Cierra la conexion (o el pool) |
| `mysql_conectar "host" puerto "basedatos" "usuario" "clave" como db (con pool N)` | Conecta a una base MySQL/MariaDB real (driver `PyMySQL`, se instala solo) |
| `mysql_ejecutar db "SQL"` | Ejecuta INSERT/UPDATE/CREATE/DELETE en MySQL |
| `mysql_ejecutar_parametrizado db "SQL con ?" con [valores]` | Igual que `mysql_ejecutar` pero con valores separados en una lista, sin armar el SQL a mano con `+` (evita inyeccion SQL) |
| `mysql_consultar db "SELECT ..." en var` | Ejecuta un SELECT en MySQL y devuelve una lista de diccionarios |
| `mysql_consultar_parametrizado db "SELECT ... ?" con [valores] en var` | Igual que `mysql_consultar` pero con valores separados (sin inyeccion SQL) |
| `mysql_cerrar db` | Cierra la conexion (o el pool) |

> En los cuatro comandos `*_parametrizado` el SQL siempre se escribe con `?` como marcador de posicion, igual que en SQLite -- SiPi lo traduce solo al estilo que necesita cada driver por dentro (`%s` en MySQL, `:pN` en PostgreSQL).

### Web (paginas y backend real)
| Comando | Que hace |
|---|---|
| `pagina_web ... fin` con `titulo`, `subtitulo`, `texto`, `enlace`, `lista_web`, `separador`, `tarjeta`, `tema`, `color`, `formulario`, `campo` | Genera una pagina HTML declarativa. Cualquier `{variable}` interpolada dentro de estos comandos se escapa automaticamente (HTML-safe) antes de insertarse -- si el valor viene de afuera (un formulario recibido, un archivo, una base de datos), no puede inyectar HTML/JS en la pagina (proteccion XSS) |
| `generar_pagina_web` | Guarda la pagina generada en disco |
| `iniciar_servidor_web "carpeta" puerto` | Levanta un servidor de archivos estaticos |
| `escuchar_ruta "/api/ruta" con funcion` | Registra una ruta de API |
| `iniciar_api_web puerto` | Levanta un backend HTTP real (GET/POST/PUT/DELETE) que despacha a funciones SiPi |
| `detener_api_web` | Apaga el servidor de API |

### Ventanas de escritorio (GUI)
| Comando | Que hace |
|---|---|
| `ventana ... fin` con `boton`, `etiqueta`, `entrada`, `imagen`, `cuadro`, `casilla`, `lista`, `barra_progreso`, `actualizar_barra`, `menu_desplegable`, `pestanias`/`pestana` | Interfaces graficas de escritorio (tkinter) |

### Juegos 2D
| Comando | Que hace |
|---|---|
| `crear_juego ... fin` con `sprite`, `sonido`, `tono`, `chocar`, `velocidad`, `puntaje_inicial`, `mostrar_puntaje`, `mover_aleatorio`, `gravedad`, `rebote`, `friccion`, `tamano_mundo`, `camara_seguir` | Motor de juegos 2D (pygame) |
| `ia`, `seguir`, `escapar`, `patrullar` | Comportamiento de IA para personajes/enemigos |
| `particulas`, `explosion`, `humo`, `fuego` | Efectos visuales |

### Sistema y utilidades
| Comando | Que hace |
|---|---|
| `ejecutar` / `esperar` | Ejecuta comandos del sistema / pausa |
| `reproducir_tono` | Sonido simple |
| `instalar_paquete` | Instala un paquete de Python (pip) que tu programa necesite |
| `obtener_url` | Peticion HTTP simple |
| `fecha_hora_actual` | Fecha y hora |
| `cada N segundos ... fin` / `detener_temporizador` | Temporizadores repetidos |
| `captura_pantalla` / `copiar_portapapeles` / `pegar_portapapeles` | Utilidades del sistema |
| `generar_app_android` / `generar_app_windows` | Empaquetado de apps |
| `modo_debug` | Activa impresion de cada linea ejecutada, para depurar |

## Concurrencia (hilos reales)

Threads reales de sistema operativo (`threading` de Python por dentro), no cooperativos. **Importante:** cada hilo trabaja con su propia copia de las variables globales tomada al momento de crearlo — no comparten estado en vivo con el resto del programa (ver `KNOWN_ISSUES.md` para el porqué). Comunicá resultados con `devolver`/`hilo_resultado`, no con variables globales.

| Comando | Qué hace |
|---|---|
| `hilo_crear funcion(args) -> id_hilo` | Corre una función en un hilo real, en paralelo, sin bloquear el resto del programa |
| `hilo_esperar id_hilo` | Bloquea hasta que ese hilo termine |
| `hilo_resultado id_hilo -> var` | Espera si hace falta y guarda lo que devolvió el hilo |
| `hilo_esta_vivo id_hilo -> var` | Revisa si sigue corriendo, sin bloquear |
| `hilo_esperar_todos` | Bloquea hasta que todos los hilos creados hasta ahora terminen |
| `bloqueo_crear nombre` | Crea un candado (lock) real para sincronizar acceso a un recurso compartido (archivo, conexión) |
| `con_bloqueo nombre ... fin` | Ejecuta el bloque con el candado tomado; se libera solo al salir, incluso si hay un error adentro |

```sipi
funcion descargar(url)
    peticion_http url -> respuesta
    devolver respuesta
fin

hilo_crear descargar("https://ejemplo.com/a") -> h1
hilo_crear descargar("https://ejemplo.com/b") -> h2
hilo_resultado h1 -> resultado_a
hilo_resultado h2 -> resultado_b
```

## Corrector automático y revisor de código (CLI)

Estos no son comandos dentro de un programa `.sipi`, son banderas de línea de comandos de `sipi.py`:

| Comando | Qué hace |
|---|---|
| `python sipi.py archivo.sipi` | Ejecuta el programa normalmente. Si encuentra errores tipográficos chicos (espacios de más, comillas curvas, un punto suelto, un comando mal escrito por poco como `decid`→`decir`), los corrige **en memoria** para esa corrida y te dice exactamente qué corrigió — el archivo en disco no cambia. |
| `python sipi.py --corregir archivo.sipi` | Corre el mismo corrector, pero **guarda** la versión corregida de vuelta en el archivo. Te lista todo lo que cambió antes de guardar. |
| `python sipi.py --revisar archivo.sipi` | Analiza el código (sin ejecutarlo) y da un reporte de seguridad, posibles bugs, estilo y sugerencias — ver detalle abajo. |
| `python sipi.py --formatear archivo.sipi` | Reindenta el archivo con 4 espacios por nivel (ya existía, ver `DOCUMENTACION.md`). |
| `python sipi.py --repl` (o `python sipi.py` sin argumentos) | Abre una consola interactiva: escribís código SiPi línea por línea y se ejecuta al toque, manteniendo variables/funciones/clases entre líneas. Soporta bloques multilínea (`si`/`funcion`/etc. se completan solos hasta su `fin`) y evalúa expresiones sueltas automáticamente (`2 + 2` imprime `4`, sin necesitar `decir`). También corrige y avisa errores tipográficos como en una ejecución normal. Salís con `salir`, `exit` o Ctrl+D. |
| `python sipi.py --depurar archivo.sipi` | Ejecuta el programa mostrando cada línea antes de correrla (igual que poner `modo_debug` como primera línea, pero sin editar el archivo). Combinable con `--sin-cache`. |

Todo esto también está disponible desde `sipi_cli.py` (o el comando `sipi` si lo tenés instalado así): `sipi repl`, `sipi corregir archivo.sipi`, `sipi analizar archivo.sipi`, `sipi depurar archivo.sipi`, `sipi formato archivo.sipi`, `sipi probar` (alias de `sipi test`).

### ¿Qué corrige el corrector automático?

- Espacios dobles/triples entre palabras (nunca dentro de un texto entre comillas — ahí el espacio es una decisión tuya).
- Comillas "curvas" (las que pone Word o el teclado del celular) cambiadas por comillas rectas, las únicas válidas en SiPi.
- Un punto suelto al final de una línea, que no forma parte de ningún texto.
- Espacios/tabs sobrantes al final de una línea.
- Un comando mal escrito por muy poco (ej. `decid` en vez de `decir`), **solo** cuando hay una única opción razonable — si es ambiguo, no toca nada y te deja el error normal de "comando desconocido" para que decidas vos.

### ¿Qué mira `--revisar`?

- **🔒 Seguridad:** credenciales escritas directo en el código (usar `variable_entorno` en su lugar), `hash_texto` usado sobre algo que parece una contraseña (usar `hash_seguro_contrasena`), consultas SQL armadas interpolando una variable directo en el texto (riesgo de inyección SQL).
- **🐛 Posibles bugs:** bloques `capturar` vacíos (un error que se atrapa pero no se hace nada con él), variables declaradas y nunca usadas, funciones definidas y nunca llamadas.
- **🎨 Estilo:** funciones muy largas, bloques anidados muchos niveles, comentarios `TODO`/`FIXME` que quedaron pendientes.
- **💡 Sugerencias:** operaciones riesgosas (archivos, red, bases de datos) sin ningún `intentar`/`capturar` en todo el programa; programas grandes sin ninguna prueba automatizada (`afirmar`).

Es un análisis básico y honesto sobre su propio alcance: agarra los problemas más comunes y más caros de cometer, no reemplaza revisar el código con atención vos mismo.

## Nota sobre esta referencia

Las categorías de Ventanas/Juegos/Web cubren muchísimos parámetros propios de cada bloque (por ejemplo, las opciones exactas de `sprite` o `tarjeta`). La forma más confiable de ver la sintaxis exacta de cada uno es mirar los ejemplos ya funcionando en la carpeta `ejemplos/`, que están probados y corren tal cual.

Para cualquier duda puntual sobre un comando que no esté 100% claro en esta referencia, la forma más rápida de confirmar la sintaxis exacta es abrir `sipi.py` y buscar `if cmd == "nombre_del_comando"` — cada instrucción del lenguaje está implementada ahí mismo, en español, con su propia expresión regular de sintaxis.


<!-- ===== FUENTE: docs/GLOSSARY.md ===== -->

# GLOSSARY — Terminología internacional

SiPi usa palabras clave en español a propósito (ver "¿Por qué existe SiPi?" en el `README.md`). Pero los *conceptos* detrás de esas palabras son los mismos que en cualquier lenguaje de programación, y tienen nombres estándar en inglés que vas a encontrar en cualquier otro lenguaje, tutorial, o entrevista de trabajo. Esta tabla conecta ambos mundos, para que aprender SiPi no te deje aislado del vocabulario que se usa afuera.

| En SiPi | Concepto | Término internacional (inglés) |
|---|---|---|
| `variable` | Un espacio con nombre que guarda un valor | **variable** |
| `funcion` | Bloque de código reutilizable, con nombre y parámetros | **function** |
| `funcion` que se llama a sí misma | Función que se llama a sí misma para resolver un problema por partes | **recursion** |
| Una función pasada como parámetro a otra (ej. en `lista_mapear numeros con doble`) | Una función usada como valor, pasada a otra función | **callback** / **higher-order function** |
| Una función corta, sin nombre propio, usada al vuelo | Función anónima definida en el lugar donde se usa | **lambda** / **anonymous function** |
| Una función que "recuerda" variables de donde fue creada | Función que retiene acceso a variables de su entorno original, aunque ese entorno ya haya terminado | **closure** |
| `clase` | Plantilla para crear objetos con datos y comportamiento propios | **class** |
| `nuevo Clase()` | Crear un objeto real a partir de una clase | **instantiation** |
| `hereda_de` | Una clase que extiende otra, reutilizando su comportamiento | **inheritance** |
| `implementa` | Obligación de que una clase tenga ciertos métodos, sin heredar la implementación | **interface** |
| Un método sobreescrito en una subclase | Que el mismo nombre de método se comporte distinto según la clase real del objeto | **polymorphism** |
| `este` | Referencia al objeto actual dentro de un método | **self** / **this** |
| `intentar` / `capturar` | Ejecutar código que puede fallar, y manejar el error sin cortar el programa | **try** / **catch** (**exception handling**) |
| `lanzar_error` | Generar un error a propósito | **throw** / **raise** |
| `enum` | Un tipo con un conjunto fijo y nombrado de valores posibles | **enum** (enumeration) |
| `estructura` | Agrupar varios datos relacionados bajo un solo nombre, sin comportamiento | **struct** |
| `seleccionar` / `caso` | Comparar un valor contra varias opciones posibles, de forma más legible que muchos `si`/`sino` encadenados | **pattern matching** / **switch-case** |
| `sipi.py` (el programa que lee y ejecuta tu código) | El programa que ejecuta tu código línea por línea, sin convertirlo antes a código nativo de la máquina | **interpreter** |
| La parte de `sipi.py` que entiende la estructura de tu código antes de ejecutarlo | El proceso de analizar el texto de tu programa y entender su estructura | **parser** / **parsing** |
| El código de máquina/formato intermedio que produciría un compilador | Convertir código fuente a un formato que la máquina ejecuta directamente, antes de correrlo (SiPi no hace esto — ver `LANGUAGE_SPEC.md`) | **compilation** |
| `.sipic` | Una versión precomputada del programa que acelera reejecuciones, sin ser código nativo | **bytecode cache** |
| `importar` / `instalar_modulo` | Traer código de otro archivo/paquete para usarlo en el tuyo | **import** / **module** / **package** |
| `variable x: entero` | Decirle al lenguaje de antemano qué tipo de dato va a tener una variable | **type annotation** |
| Que SiPi permita variables sin anotar tipo, y que ese tipo pueda cambiar | Que el tipo de una variable se determina y puede cambiar en tiempo de ejecución, no antes | **dynamic typing** |
| `-> variable` (patrón de comandos que calculan algo) | Un valor que una operación produce y se guarda | **return value** |
| `romper` / `continuar` | Cortar un bucle antes de tiempo, o saltar a la siguiente vuelta | **break** / **continue** |
| `nulo` | Un valor que representa "sin valor" | **null** / **None** |
| Navegación segura con `?` | Acceder a un campo que podría no existir, sin que el programa se caiga | **optional chaining** / **safe navigation** |
| `\|>` (pipe operator) | Encadenar el resultado de una operación como entrada de la siguiente, de forma legible | **pipe operator** |

## Por qué importa esto

Si en algún momento pasás de SiPi a otro lenguaje (Python, JavaScript, Java, lo que sea), vas a encontrar estos mismos conceptos con estos mismos nombres en inglés — en la documentación oficial de ese lenguaje, en Stack Overflow, en una entrevista de trabajo. Aprender la idea en SiPi ya es aprender el concepto; esta tabla es el puente para que también sepas cómo se llama afuera.
