# BYTE WARS — Tema 6
## Mini máquina virtual y bytecode

**Universidad Interamericana de Panamá · Materia: Compiladores**

> Versión descargable de la documentación completa del portal. Incluye lenguaje, compilador, bytecode, máquina virtual, juego, arquitectura, proceso, resultados y pruebas.

---

## 1. Resumen

**BYTE WARS** es un juego 2D en el navegador donde la nave no se controla con el teclado: se controla con un programa escrito en **BWL (Byte Wars Language)**. El programa se compila a **bytecode** y una **máquina virtual** propia ejecuta cada instrucción para mover, disparar y activar el escudo.

El núcleo completo —lexer, parser, análisis semántico, generador de bytecode, VM y motor del juego— está escrito en **C99** y se compila a **WebAssembly** con **Emscripten**. El mismo núcleo se compila también a binarios nativos para pruebas y demostración.

```
código BWL
   │
   ▼
lexer → parser → AST → análisis semántico → bytecode
   │
   ▼
máquina virtual (PC, pila, variables, saltos, WAIT)
   │
   ▼
juego 2D (Canvas): naves, balas, escudo, salud, puntuación y oleadas
```

---

## 2. Equipo

- Carlos Zachrisson
- Karen Arauz

---

## 3. Proceso

| Fase | Actividad | Resultado |
|---|---|---|
| 0 | Análisis del portal existente, copia de seguridad y commit inicial | Línea base protegida; Temas 11 y 4 conservados en `legacy/` |
| 1 | Especificación de BWL, lexer y parser | Tokens, AST y errores con línea/columna |
| 2 | Análisis semántico, símbolos y generación de bytecode | Bytecode y desensamblador |
| 3 | VM, juego determinista y CLI nativo | Ejecución, bucles, WAIT, colisiones y oleadas |
| 4 | Puente WebAssembly con Emscripten | `bytewars.wasm` de 87 KB y `bytewars.js` |
| 5 | Interfaz web | Tablero de cuatro paneles y análisis del compilador |
| 6 | Documentación y capturas | Documentación, README y entregables |
| 7 | QA final, responsive, accesibilidad y Docker | Chromium headless, móvil 390 px, Docker build y contenedor |

### Decisiones técnicas

- **C99 para todo el núcleo:** compilador, VM y juego comparten el mismo código en WASM y nativo.
- **Ejecución en el cliente:** el servidor no ejecuta código del usuario; el WASM es el sandbox.
- **VM de pila:** fácil de explicar, visualizar y probar.
- **Arenas estáticas y límites:** comportamiento predecible y sin fugas.
- **PRNG xorshift32 con semilla fija:** pruebas y partidas reproducibles.
- **Interfaz desacoplada:** la UI consume snapshots JSON.
- **Un nivel de tres oleadas:** alcance del MVP; el selector de nivel ajusta la dificultad.
- **Juego a pantalla completa (PC y móvil):** al ejecutar, el juego se fija sobre la página con HUD y controles, precedido por una cuenta regresiva 3 · 2 · 1; evita el scroll entre el editor y el panel 4.
- **Tema claro/oscuro:** variables CSS, detección de la preferencia del sistema, botón sol/luna y persistencia en `localStorage`. El canvas del juego queda oscuro para conservar el contraste del espacio.

### Dificultades y soluciones

| Dificultad | Solución |
|---|---|
| Constantes decimales en un operando entero | Campo `double num` en `BwInstr` para `PUSH` |
| Bucles infinitos que congelan la página | Presupuesto de 200 instrucciones por tick y cesión de turno |
| Acoplamiento VM/juego | `BwHost` con callbacks y host falso en pruebas |
| Errores de memoria en C | Arenas estáticas, límites y validación de índices |
| Ocultar los Temas 11 y 4 sin borrarlos | Copias en `legacy/` y menú principal centrado en el Tema 6 |
| Wasm bloqueado con `file://` | Servidor HTTP y mensajes de diagnóstico |

---

## 4. Resultados

La aplicación permite escribir, compilar, inspeccionar y ejecutar un programa completo. El tablero muestra los cuatro paneles conectados en tiempo real.

### Qué funciona

- Compilación con errores de léxico, sintáctico y semántico, con línea y columna.
- Bytecode visible, instrucción actual resaltada y desensamblador con direcciones.
- VM con PC, pila, variables reservadas y de usuario, ticks y estado.
- Modo tiempo real y modo paso a paso.
- Movimiento, disparo, escudo, espera, bucles, condicionales y builtins.
- Juego con salud, puntuación, oleadas, enemigos que disparan y victoria/derrota.
- Protección contra bucles infinitos y errores de ejecución.
- Interfaz con juego a pantalla completa en PC y móvil, cuenta regresiva 3 · 2 · 1 y botón flotante para volver.
- Tema claro/oscuro con botón sol/luna y persistencia.
- Descarga de `bytewars.exe` y `bytewars_cli`.

### Métricas medidas

| Métrica | Resultado |
|---|---|
| Tiempo de compilación del ejemplo (23 instrucciones) | ≈ 0.2 ms en el navegador |
| Serialización de un frame de juego | ≈ 0.03 ms |
| Tamaño de `bytewars.wasm` | 87 KB |
| Tamaño de `bytewars.js` | 19 KB |
| Tamaño de `bytewars_cli` / `bytewars.exe` | 69 KB / 98 KB |
| Pruebas unitarias en C | 16 grupos, todos pasando |
| Límite de instrucciones por tick | 200, con cesión de turno |

### Limitaciones conocidas

- Un nivel de tres oleadas; el selector de nivel ajusta la dificultad, no añade mapas nuevos.
- Sin sonido ni multijugador.
- `bytewars.exe` es un runner de consola, no una ventana gráfica nativa.
- La VM es didáctica; no emula hardware real.

---

## 5. Lenguaje BWL

BWL es un lenguaje imperativo pequeño, con bloques, expresiones aritméticas y lógicas, variables y llamadas a funciones integradas.

```bwl
// Estrategia básica
START
SET speed 3
REPEAT 5 {
  MOVE RIGHT
  SHOOT
  WAIT 10
}
WHILE enemy_ahead() {
  IF health < 30 {
    SHIELD
  } ELSE {
    SHOOT
    MOVE UP
  }
}
END
```

### Gramática

```ebnf
programa       := sentencia*
sentencia      := 'START' | 'END'
                | 'SET' IDENT expresion
                | 'MOVE' ('UP'|'DOWN'|'LEFT'|'RIGHT')
                | 'SHOOT' | 'SHIELD'
                | 'WAIT' expresion
                | 'REPEAT' expresion bloque
                | 'WHILE' expresion bloque
                | 'IF' expresion bloque ('ELSE' bloque)?
bloque         := '{' sentencia* '}'
expresion      := or
or             := and ('||' and)*
and            := igualdad ('&&' igualdad)*
igualdad       := comparacion (('=='|'!=') comparacion)*
comparacion    := suma (('<'|'>'|'<='|'>=') suma)*
suma           := multiplicacion (('+'|'-') multiplicacion)*
multiplicacion := unario (('*'|'/'|'%') unario)*
unario         := ('-'|'!') unario | primario
primario       := NUMERO | IDENT | IDENT '(' argumentos? ')'
                | '(' expresion ')' | 'TRUE' | 'FALSE'
```

### Variables reservadas

| Nombre | Tipo | Significado |
|---|---|---|
| `health` | 0–100 | Salud de la nave |
| `score` | número | Puntuación |
| `enemies_left` | número | Enemigos vivos |
| `level` | número | Nivel actual |
| `shield` | 0/1 | Escudo activo |
| `ticks` | número | Ticks de juego |

Las variables del usuario se crean con `SET` y deben existir antes de leerse. Los nombres reservados son de solo lectura.

### Funciones integradas

| Función | Argumentos | Devuelve |
|---|---|---|
| `enemy_ahead()` | 0 | 1 si hay un enemigo delante |
| `enemy_left()` | 0 | 1 si hay un enemigo a la izquierda |
| `enemy_right()` | 0 | 1 si hay un enemigo a la derecha |
| `random(n)` | 1 | Entero pseudoaleatorio entre 0 y n-1 |

### Límites

- Fuente: 16 KB; tokens: 2048; nodos del AST: 2048; instrucciones: 2048; variables: 64; pila: 256.
- Profundidad de bloques/expresiones: 64.
- `WAIT`: 0–600 ticks. `REPEAT`: hasta 10 000 iteraciones por entrada.
- 200 instrucciones de VM por tick de juego para evitar bloqueos.

---

## 6. Compilador

El compilador está en `bytewars/src/` y se organiza en fases separadas.

| Archivo | Responsabilidad |
|---|---|
| `lexer.c` | Convierte el texto en tokens con línea y columna; ignora comentarios `//`. |
| `parser.c` | Descenso recursivo; construye el AST y reporta errores sintácticos. |
| `sema.c` | Tabla de símbolos, variables reservadas, builtins, aridad y división entre cero literal. |
| `codegen.c` | AST → bytecode, parcheo de saltos y desensamblador. |
| `compiler.c` | Orquesta las fases y conserva los diagnósticos. |

### Ejemplo de AST

```
Programa
  START
  SET speed
    NUM 3
  REPEAT
    NUM 5
    BLOQUE
      MOVE RIGHT
      SHOOT
      WAIT
        NUM 10
  WHILE
    BINARIO >
      VAR health
      NUM 0
    BLOQUE
      IF
        CALL enemy_ahead (0 args)
        BLOQUE
          SHOOT
      ELSE
        BLOQUE
          WAIT
            NUM 3
  END
```

### Errores por fase

| Fase | Ejemplo |
|---|---|
| Léxico | `SET x @` → «Carácter no reconocido» |
| Sintáctico | Falta `}` → «Se esperaba '}'…» |
| Semántico | `SET x y` → «Variable no definida 'y'»; `SET health 5` → variable reservada |
| Ejecución | División entre cero dinámica, pila vacía, salto inválido |

---

## 7. Bytecode e ISA

Cada instrucción tiene un opcode, un operando entero, la línea del fuente y, para `PUSH`, una constante decimal.

```c
typedef struct {
    uint8_t op;
    int32_t arg;      // variable, dirección o builtin
    int16_t line;     // línea del fuente
    double  num;      // constante de PUSH
} BwInstr;
```

| Opcode | Operando | Pila | Descripción |
|---|---|---|---|
| `PUSH` | número | +1 | Empuja una constante |
| `LOAD` / `STORE` | variable | +1 / −1 | Lee o escribe una variable |
| `ADD SUB MUL DIV MOD` | — | −1 | Aritmética |
| `NEG NOT` | — | 0 | Negación aritmética o lógica |
| `LT GT LE GE EQ NE` | — | −1 | Comparaciones (1 o 0) |
| `AND OR` | — | −1 | Lógica |
| `JMP JZ JNZ` | dirección | 0 / −1 | Saltos |
| `CALL` | builtin | variable | Llama a una función integrada |
| `MOVE_UP/DOWN/LEFT/RIGHT` | — | 0 | Mueve la nave |
| `SHOOT SHIELD` | — | 0 | Acciones de combate |
| `WAIT` | — | −1 | Espera n ticks |
| `REPEAT_START / REPEAT_END` | dirección | −1 / 0 | Bucle contado |
| `HALT` | — | 0 | Detiene la VM |

### Desensamblado del ejemplo

```text
0000  PUSH           3
0001  STORE          speed
0002  PUSH           5
0003  REPEAT_START   0009
0004  MOVE_RIGHT
0005  SHOOT
0006  PUSH           10
0007  WAIT
0008  REPEAT_END
0009  LOAD           health
0010  PUSH           0
0011  GT
0012  JZ             0022
0013  CALL           enemy_ahead
0014  JZ             0017
0015  SHOOT
0016  JMP            0019
0017  PUSH           3
0018  WAIT
0019  PUSH           2
0020  WAIT
0021  JMP            0009
0022  HALT
```

---

## 8. Máquina virtual

La VM es de pila y mantiene todo el estado visible en la interfaz.

```c
typedef struct {
    BwInstr code[2048]; int code_len;
    BwVar   vars[64];   int var_count;
    double  stack[256]; int sp;
    int pc;
    BwLoopFrame loops[32]; int loop_sp;
    int wait_ticks, halt_ticks, status;
    long steps, ticks;
    int budget_hits, has_error;
    BwDiag error;
    BwHost host;
} BwVM;
```

- **Ejecución:** cada tick de juego ejecuta hasta 200 instrucciones o hasta `WAIT`/`HALT`.
- **Espera:** `WAIT n` deja la VM esperando n ticks.
- **Bucles:** `REPEAT_START` guarda el contador en una pila de bucles; `REPEAT_END` lo decrementa.
- **Saltos:** `JZ`/`JNZ` validan que la dirección exista.
- **Errores:** pila vacía, división entre cero, variable inválida, salto inválido, opcode desconocido, presupuesto excedido.
- **Reinicio:** al llegar a `HALT`/`END`, el programa se reinicia tras 30 ticks para seguir controlando la nave.
- **Host:** la VM recibe un `BwHost` con callbacks (`move`, `shoot`, `shield`, `builtin`, `status`); no conoce el juego directamente.

---

## 9. Juego

### Reglas

- Área lógica de 480 × 640.
- La nave se mueve en la parte inferior; los límites se respetan.
- Disparo con recarga; escudo temporal con recarga.
- Enemigos exploradores, cazadores y tanques.
- Salud 100; daño por impactos y por enemigos que cruzan la línea.
- Victoria al limpiar tres oleadas; derrota si la salud llega a 0.

### Determinismo

Todo el azar usa un PRNG **xorshift32** con semilla fija. El mismo programa, nivel y semilla producen el mismo resultado, lo que permite pruebas automáticas de colisiones, victoria y derrota sin depender del tiempo real.

El selector de nivel 1–3 ajusta velocidad, tipos de enemigo y frecuencia de disparo.

---

## 10. Arquitectura y tecnologías

```
Navegador
  tema6.html + bytewars.js
    ├── editor, paneles, canvas
    └── ByteWarsModule (WebAssembly)
          ├── lexer.c → parser.c → sema.c → codegen.c
          ├── vm.c
          └── game.c → json.c
Servidor Node
  ├── sirve public/
  ├── /builds/ (proyecto anterior, intacto)
  └── scripts/build-bytewars.sh → public/wasm
Nativo
  ├── bytewars_cli (Linux)
  └── bytewars.exe (Windows, consola)
```

| Tecnología | Uso |
|---|---|
| C99 | Compilador, VM y juego |
| Emscripten | C → WebAssembly |
| WebAssembly | Ejecución en el navegador |
| HTML/CSS/JS | Editor, paneles y controles |
| Canvas 2D | Naves, balas y fondo procedural |
| mingw-w64 | Runner `.exe` de consola |
| Node.js | Servidor HTTP y scripts |

---

## 11. Interfaz

### Paneles

1. **Código fuente:** editor BWL con resaltado, números de línea, errores y atajos.
2. **Bytecode generado:** direcciones, opcode, operando e instrucción actual.
3. **Ejecución en la VM:** instrucción actual, PC, pila, variables, ticks y estado.
4. **Juego en tiempo real:** canvas, HUD, salud, escudo, puntuación y nivel.

### Juego a pantalla completa (PC y móvil)

Al pulsar **Compilar y ejecutar**, el juego se abre a pantalla completa tanto en PC como en móvil, con una cuenta regresiva **3 · 2 · 1** antes de comenzar:

- Canvas y HUD.
- Instrucción actual, PC y ticks.
- Botones de pausa, paso a paso, reinicio y volver al editor.
- Botón flotante **Ver juego / Ver resultado** en móvil cuando el panel está cerrado.

El panel bloquea el scroll mientras está abierto y se cierra con `Esc` o con «Volver al editor». Si se cierra durante la cuenta regresiva, la partida se cancela.

### Tema claro/oscuro

- Botón sol/luna en la barra superior de Inicio, Juego y Documentación.
- Detecta `prefers-color-scheme` y guarda la preferencia en `localStorage`.
- El canvas del juego se mantiene oscuro para conservar el contraste del espacio y los láseres.

---

## 12. Cómo ejecutar

Requisitos: **Node 18+**, **gcc**, **Emscripten** y, opcionalmente, **mingw-w64** para el `.exe`.

```bash
# 1. Construir el núcleo (WASM + binarios nativos)
npm run build:bytewars

# 2. Arrancar el portal
npm start
#    http://localhost:3000

# 3. Pruebas
npm test

# 4. Solo el núcleo C
make -C bytewars test
make -C bytewars cli
```

Si falta el WASM, `npm start` intenta construirlo automáticamente. La página debe servirse por HTTP, no abrirse con `file://`, porque el navegador bloquea la carga del módulo WebAssembly.

### Docker

```bash
docker compose up -d --build
```

La imagen instala Node, gcc, mingw-w64 y Emscripten, y compila el WASM durante el build.

---

## 13. Pruebas

```text
== Pruebas de BYTE WARS ==
lexer
parser
errores por fase
codegen
vm aritmética
vm if/else
vm repeat/while
vm error de ejecución
vm wait
vm acciones y builtins
vm límite por tick
juego límites
juego disparo/escudo
juego determinista
programa de ejemplo
json

Todas las pruebas pasaron.
```

| Nivel | Qué comprueba |
|---|---|
| Lexer | Palabras clave, identificadores, números, comentarios y errores. |
| Parser | Bloques, precedencia, IF/ELSE, REPEAT/WHILE y errores. |
| Semántica | Variables no definidas, reservadas, builtins, aridad y división literal. |
| Codegen | Instrucciones, saltos parcheados, desensamblador y límites. |
| VM | Aritmética, ramas, bucles, WAIT, builtins, errores y presupuesto. |
| Juego | Límites, disparo, escudo, determinismo y colisiones. |
| Integración | Los ejemplos compilan; el ejemplo con errores falla; el frame contiene VM y juego. |
| Navegador | Carga del WASM, compilación, ejecución, pausa, paso a paso y variables en vivo. |

---

## 14. Descargas

| Archivo | Descripción |
|---|---|
| `bytewars.exe` | Runner de consola para Windows (64 bits). Si se abre sin argumentos, ejecuta una demo incluida. |
| `bytewars_cli` | Runner para Linux. |
| `bytewars.wasm` | Núcleo compilado para el navegador. |

Uso del runner:

```bash
bytewars.exe programa.bwl
bytewars.exe --ticks 900 --seed 12345 --level 1 programa.bwl
bytewars.exe --json programa.bwl
```

Los archivos están disponibles en la sección **Descargas** del portal.

---

## 15. Conclusiones

BYTE WARS demuestra que un compilador y una máquina virtual escritos en C pueden ser el centro de un juego real y ejecutarse en el navegador sin instalar nada. El jugador ve el ciclo completo: escribe una estrategia, observa los tokens y el AST, revisa el bytecode, sigue la ejecución de la VM y comprueba el efecto en la nave.

El proyecto separa claramente las responsabilidades: el compilador no dibuja, la VM no conoce el juego y la interfaz solo consume snapshots JSON. Esa separación permitió probar cada parte por separado y mantener el juego determinista.

---

## 16. Enlaces

- Documentación web: `documentacion.html`
- Juego: `tema6.html`
- Portada: `index.html`
- Repositorio: proyecto `temporal_taller_colaborativo`
- Los Temas 11 y 4 se conservan en `legacy/` y fuera del menú principal.

---

**BYTE WARS · Tema 6 · Mini máquina virtual y bytecode**
Universidad Interamericana de Panamá · Materia: Compiladores
